diff --git a/.env b/.env index c2fa2420..eda2e563 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ ################################################## -# -# General settings for your component +# +# General settings for your component # ################################################## @@ -8,55 +8,111 @@ # Enviroment settings ################################################## -# Depracticed, now set as CONTAINER_PROJECT_NAME +# The shortcode for this component, should be a small set of letters reprecentint the application APP_NAME=bs -# Do you want to dsiplay the symfony debug toolbar? +# The Full title of the application +APP_TITLE=Berichten Service +# The current version of the application +APP_VERSION=V.0.1 APP_DEBUG=1 # What is the enviroment type you want to use for local production? (choose between dec,stag,prod, acce or test) APP_ENV=dev +# We use a build to tag images, this is swithced to the version on master and to env on other branches +APP_BUILD=dev +# The description for this api +APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' + + +APP_LOGO=pc.zaakonline.nl +APP_HOME=pc.zaakonline.nl + +# The urls on wich this api is available +TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +TRUSTED_HOSTS=^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost + +################################################## +# Orgization details +################################################## + +# The following details describe your organisations and are used for both certificate creation, nlx (if active) and common-ground.dev + +ORGANIZATION_NAME=Conduction +ORGANIZATION_EMAIL_ADDRESS=info@conduction.nl +ORGANIZATION_COUNTRY_NAME=Netherlands +ORGANIZATION_STATE=Noord-Holland +ORGANIZATION_LOCALITY=Amsterdam +ORGANIZATION_UNIT_NAME=Common-Ground ################################################## # Documentation settings ################################################## -APP_DEMO=dev -APP_REPRO=dev +# The subdomain for this component (should be www for applications) +APP_SUBDOMAIN=bs +# he domains on wich you want to provide this component, the first wil be used as primary (or common in cert-manger terms) +APP_DOMAINS=["conduction.nl","zaakonline.nl","huwelijksplanner.online","common-ground.dev"] + + +# The demo enviroment for this component @depracticed +APP_DEMO=pc.zaakonline.nl +# he Repository for this component +APP_REPRO=https://github.com/ConductionNL/Proto-component-commonground ################################################## # Docker settings ################################################## CONTAINER_REGISTRY_BASE=docker.io/conduction -CONTAINER_PROJECT_TITLE=Berichten Service CONTAINER_PROJECT_NAME=bs CONTAINER_PROJECT_VERSION=V.0.1 +CONTAINER_REPRO=https://hub.docker.com/repository/docker/conduction/bs-php ################################################## -# Websub settings +# Notifcation settings ################################################## -WEBSUB_PROVIDER=sasd -WEBSUB_AUTHORIZATION=sasd +NOTIFICATION_ENABLED=falsedxfddxf +NOTIFICATION_PROVIDER=sasdasd +NOTIFICATION_ENABLED_AUTHORIZATION=sasd ################################################## # Authorization settings ################################################## -AUTH_PROVIDER=sasd +AUTH_ENABLED=false +AUTH_PROVIDER=sasdadad AUTH_AUTHORIZATION=sasd ################################################## -# NLX Setup, read more at https://docs.nlx.io/get-started/# +# Auditrail settings +################################################## + +AUDITTRAIL_ENABLED=false + +################################################## +# Healthcheck settings +################################################## + +HEALTH_ENABLED=false + +################################################## +# Archive settings +################################################## + +ARCHIVE_ENABLED=false + +################################################## +# NLX Setup, read more at https://docs.nlx.io/get-started/# ################################################## # Do you want to provide an nlx outway? (option for your component to reach nlx services) -NLX_OUTWAY=true +NLX_OUTWAY=true # Do you want to provice an nlx inway (option for nlx services to reach your api) -NLX_INWAY=false +NLX_INWAY=false # NLX Certification Details -NLX_COUNTRY_NAME=Netherlands +NLX_COUNTRY_NAME=Netherlands NLX_STATE=Noord-Holland NLX_LOCALITY=Amsterdam NLX_ORGANIZATION_NAME=Conduction diff --git a/.github/IMAGES/travis activate repository.PNG b/.github/IMAGES/travis activate repository.PNG new file mode 100644 index 00000000..cd2f8b12 Binary files /dev/null and b/.github/IMAGES/travis activate repository.PNG differ diff --git a/.github/IMAGES/travis enviroment variables filed in.PNG b/.github/IMAGES/travis enviroment variables filed in.PNG new file mode 100644 index 00000000..ddd960df Binary files /dev/null and b/.github/IMAGES/travis enviroment variables filed in.PNG differ diff --git a/.github/IMAGES/travis enviroment variables.PNG b/.github/IMAGES/travis enviroment variables.PNG new file mode 100644 index 00000000..894de1a5 Binary files /dev/null and b/.github/IMAGES/travis enviroment variables.PNG differ diff --git a/.github/deploy.yml b/.github/deploy.yml new file mode 100644 index 00000000..3bd4c3c9 --- /dev/null +++ b/.github/deploy.yml @@ -0,0 +1,4 @@ +# View examples and documentation at https://deliverybot.dev/docs/ +production: + environment: production + production_environment: true diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml new file mode 100644 index 00000000..18454a2d --- /dev/null +++ b/.github/workflows/dockerimage.yml @@ -0,0 +1,135 @@ +name: Docker Image CI + +on: + pull_request: + branches: + - master + - staging + - development + push: + branches: + - master + - staging + - development + +jobs: + + build: + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Setting APP_NAME + run: | + export NAME=$(grep APP_NAME= .env | cut -d '=' -f2) + echo ::set-env name=APP_NAME::$NAME + - name: Print app name + run: echo "APP_NAME = $APP_NAME" + - name: Setting APP_ENV to dev + run: | + echo ::set-env name=APP_ENV::dev + echo ::set-env name=APP_BUILD::dev + echo "set APP_ENV to $APP_ENV" + - name: Setting APP_ENV to prod + if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) + run: | + echo ::set-env name=APP_ENV::prod + echo ::set-env name=APP_BUILD::prod + echo "set APP_ENV to $APP_ENV" + - name: Set APP_BUILD to APP_VERSION + if: contains( github.ref, 'master' ) + run: | + export VERSION=$(grep APP_VERSION= .env | cut -d '=' -f2) + echo ::set-env name=APP_BUILD::$VERSION + echo "set APP_BUILD to $APP_BUILD" + - name: Setting APP_ENV to stag + if: contains( github.ref, 'staging' ) || contains( github.base_ref, 'staging' ) + run: | + echo ::set-env name=APP_ENV::stag + echo ::set-env name=APP_BUILD::stag + echo "set APP_ENV to $APP_ENV" + - name: Print definitive APP_ENV + run: echo "APP_ENV is now $APP_ENV" + - name: Build the Docker image + run: docker-compose build --pull --build-arg APP_ENV=$APP_ENV --build-arg APP_BUILD=$APP_BUILD + - name: Run the docker image + run: docker-compose up -d + - name: Taking some sleep (for containers to come up) + run: sleep 200 + - name: Check if all containers are running + run: docker ps + - name: Dumping the logs + run: docker-compose logs + - name: Database Update + run: docker-compose exec -T php bin/console doctrine:schema:update --force + #- name: Taking some more sleep (for database to be updated) + # run: sleep 20 + #- name: Database Check + # run: docker-compose exec -T php bin/console doctrine:schema:validate + - name: Security Checks + run: docker-compose exec -T php composer req sensiolabs/security-checker + + - name: Chores + run: docker-compose down + - name: Login to DockerHub Registry + id: dockerhub-login + run: | + if [ "${{ secrets.DOCKERHUB_PASSWORD }}" != "" ] && [ "${{ secrets.DOCKERHUB_USERNAME }}" != "" ]; then + echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + echo "##[set-output name=success;]true" + else + echo "##[set-output name=success;]false" + fi + - if: steps.dockerhub-login.outputs.success == 'true' + name: Push to docker hub + run: docker-compose push + - name: Create kube config + id: kubeconfig + if: contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' ) + run: | + if [ "${{ secrets.KUBECONFIG }}" != "" ]; then + printf "${{ secrets.KUBECONFIG }}" > kubeconfig.yaml + echo "##[set-output name=success]true" + else + echo "##[set-output name=success]false" + fi + - name: Set correct helm version + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: helm init --upgrade --kubeconfig="kubeconfig.yaml" + - name: Deploy through helm + id: helm-install + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: helm upgrade $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + - name: Install through helm + if: failure() && (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' + run: helm install --name $APP_NAME-$APP_ENV ./api/helm --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV --set settings.env=$APP_ENV,settings.debug=1 + - name: Rollout new containers + if: (contains( github.ref, 'master' ) || contains( github.ref, 'staging' ) || contains( github.ref, 'development' )) && steps.kubeconfig.outputs.success == 'true' && success() + run: | + kubectl rollout restart deployment/$APP_NAME-php --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + kubectl rollout restart deployment/$APP_NAME-nginx --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + kubectl rollout restart deployment/$APP_NAME-varnish --kubeconfig="kubeconfig.yaml" --namespace=$APP_ENV + - name: Export release code + if: (success() || failure()) + id: releasecode + run: | + export RELEASE=$APP_BUILD-$(git rev-parse --short $GITHUB_SHA) + echo "##[set-output name=releasename]$RELEASE" + - name: Print release name + if: (success() || failure()) + run: echo $RELEASENAME + env: + RELEASENAME: ${{ steps.releasecode.outputs.releasename }} + - name: Create Release + if: contains( github.ref, 'master' ) && steps.kubeconfig.outputs.success == 'true' && ( success() || failure() ) + id: create_release + uses: actions/create-release@v1 + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ steps.releasecode.outputs.releasename }} + release_name: ${{ steps.releasecode.outputs.releasename }} + draft: false + prerelease: false + diff --git a/.gitignore b/.gitignore index c4dd0691..baa17284 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ api/helm/kubeconfig.yaml !/api/public/bundle/* + +.idea/ diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..ced0c1eb --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,375 @@ + + + + + + + + + + $PROJECT_DIR$/api/composer.json + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1573726460744 + + + 1573726496674 + + + 1573733386819 + + + 1573735733551 + + + 1574770855136 + + + 1575279662940 + + + 1575279748074 + + + 1575280067186 + + + 1575280181182 + + + 1575281141670 + + + 1575282235015 + + + 1575282356507 + + + 1575282386363 + + + 1575282997667 + + + 1575283562491 + + + 1575283747919 + + + 1575283918851 + + + 1575379056373 + + + 1575383847583 + + + 1575386337848 + + + 1575388288073 + + + 1575443809720 + + + 1575443827717 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 00000000..11794373 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1 @@ +# AUTHORS diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..12501b42 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 2019-11-11 (v.0.0.1) + +- Initial public release \ No newline at end of file diff --git a/DESIGN.md b/DESIGN.md deleted file mode 100644 index 154ca104..00000000 --- a/DESIGN.md +++ /dev/null @@ -1,195 +0,0 @@ -#Design Considerations - -This component was designed inline with the [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index), [commonground principles](https://vng.nl/onderwerpenindex/bestuur/samen-organiseren-2019/common-ground) and international standards. - -The spefic goal of this component is to provide a common architecture for common ground components as such the common ground principles are leading in design choices, and within those principles technological invoation and international complyancy is deemd most inportant. WE DO NOT WANT TO MAKE CONSESIONS TO CURRENT INFRASTRUCTURE. As such the component might differ on [NL API Strategie](https://docs.geostandaarden.nl/api/API-Strategie), [NORA](https://www.noraonline.nl/wiki/Standaarden), [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/index) and other standards if they are deemed incompatible or out of line with international standards. - -Domain Build-up and routing -------- -By convention the component assumes that you follow the common ground domain name build up, meaning {enviroment}.{component}.{rest of domain}. That means that only the first two url parts are used for routing. It is also assumed that when no envirment is supplied the production enviroment should be offerd E.g. a propper domain for the production API of the verzoeken registratie component would be prod.vrc.zaakonline.nl but it should also be reachable under vrc.zaakonline.nl. The proper location for the development enviroment shoud always be dev.vrc.zaakonlin.nl - -Enviroments and namespacing -------- -We assume that for that you want to run several enviroments for development purposes. We identify the following namespaces for support. -- prod (Production) -- acce (Acceptation) -- stag (Staging) -- test (Testing) -- dev (Development) - -Becouse we base the commonground infastructure on kubernetes, and we want to keep a hard sepperation between enviroment we also assume that you are using your enviroment as a namespace - -Symfony libary managment gives us the optoin to define the libbarys on a per envirmoent base, you can find that definition in the [bundle config](api/config/bundles.php) - -Besides the API envormiments the component also ships with aditional tools/enviroments but those are not meant to be deployed -- client (An react client frontend) -- admin ( An read admin interface) - -On the local development docker deploy the client enviroment is used as default in stead of the production version of the api. - -Loging Headers (NLX Audit trail) -------- -@todo update, a reaction about this has been given by the NLX team. - -We inherit a couple of headers from the transaction logging within the [NLX schema](https://docs.nlx.io/further-reading/transaction-logs/), we strongly discurage the use of the `X-NLX-Request-Data-Subject` header as it might allow private data (such as BSN's) to show up in logging. - -__solution__ -The follwoing X-NLX headers have been implemented `X-NLX-Logrecord-ID`,`X-NLX-Request-Process-Id`,`X-NLX-Request-Data-Elements` and `X-NLX-Request-Data-Subject`, these are tied to the internal audit trail (see audit trail for more information), and `X-Audit-Toelichting` (from the ZGW API's) is implemented as `X-Audit-Clarification` - -Api versioning -------- -As per [landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning) major versions in endpoint minor versions in header, for this the `API-Version` is used (instead of the `api-version` header used in haal centraal) - -Fields -------- -A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of field limitations has been introduced its general purpose being to allow an application to limit the returned fields to prevent the unnecessary transportation of (private) data. In the [NL API Strategie](https://github.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/blob/master/features/fields.feature) this has been implemented as a parameter consisting of comma separated values. However the normal web standard for optional lists (conform w3c form standards) is an array. - -__solution__ -The fields parameter and functionality has been implemented as an array - -Extending -------- -A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Perso on/openapi.yaml) the concept of extending has been introduced, its general purpose being to allow the inclusion of sub resources at an api level thereby preventing unnecessary API calls. In the [NL API Strategie](https://github.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/blob/master/features/expand.feature) this has been implemented as a parameter consisting of comma separated values. However the normal web standard for optional lists (conform w3c form standards) is an array. - -__solution__ -The extend parameter has been implemented as an array - -Archivation -------- -In line with the extending and fields principle whereby we only want resources that we need it was deemed, nice to make a sub resource of the archivation properties. This also results in a bid cleaner code. - - -Audittrail -------- -@todo this needs to be implemented -For notifications we use the base mechanism as provided by [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) but we differ on insight into the data that should be returned and feel that the international standard [RFC 3881](https://tools.ietf.org/html/rfc3881) should have been followed here. - -__solution__ -In compliance with [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) each individual object should support an /audittrail endpoint. You can look into the [tutorial](TUTORIAL.md) for specifications on how to activate an audit trail for a given object. However, instead of the values mention in the vng.cloud design we follow [RFC 3881](https://tools.ietf.org/html/rfc3881) for the return values. And we give NLX values precedence if provided. - -Notifications -------- -@todo this needs to be implemented -For notifications we do not use the current [ZGW standard](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/notificaties) since we deem it insecure to send properties or data objects along with a notification. This is a potential security breach explained [here](https://github.com/VNG-Realisatie/gemma-zaken/issues/1427#issuecomment-549272696). It also doesn’t follow the [web standard](https://www.w3.org/TR/websub/). Instead we are developing our own subscriber service that is tailored for the NLX / VNG environment and based on current web standards [here](). - -__solution__ -In compliance with [w3.org](https://www.w3.org/TR/websub/) each endpoint returns an header containing an subscribtion url. That can be used in acordanse with the application to subscribe to both individual objects as collections. whereby collections serve as 'kanalen'. - -Scopes, Authentication and Authorization -------- -@todo this needs to be implemented -We implement user scopes as per [vng.cloud](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/autorisatie-scopes) standard. But see problems with how the scopes are defined and named, and consider the general setup to be to focused on ZGW (including Dutch naming, zgw specific fields like maxVertrouwlijkheid and a lack of CRUD thinking). There is a further document concerning [Authentication and Authorization](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/authenticatie-autorisatie) that details how we should authenticate users and give them scopes. We agree with the principles of the document on application based authorization and the use of JWT tokens. But disagree on some key technical aspect. Most important being that the architecture doesn't take into consideration the use of one component by several organizations - -__solution__ -No solution as of yet, so there is no implementation of Authorization or Scopes. We might build a new Authorization Component in the long run. - - -Timetravel -------- -A part of the [haal centraal](https://raw.githubusercontent.com/VNG-Realisatie/Haal-Centraal-BRP-bevragen/master/api-specificatie/Bevraging-Ingeschreven-Persoon/openapi.yaml) the concept of timetravel has been introduced, as in getting the version of an object as it was on a given date. For this the `geldigop` [see the docs](file:///C:/Users/ruben/Desktop/doc_gba_historie.html#operation/getBewoningen) header is used. In addition the `geldigvan` and `geldigtot` are introduced as collection filters. - -The commonground proto componant natively supports time traveling on all entities that are annotaded with the @Gedmo\Loggable, this is done by adding the ?validOn=[date] query to a request, date can either be a datetime or datedatime string. Any value supported by php's [strtotime()](https://www.php.net/manual/en/function.strtotime.php) is supported. Keep in mind that this returns the entity a as it was valid on that time or better put, the last changed version BEFORE that moment. To get a complete list of all changes on a item the ?showLogs=true quarry can be used. - -__solution__ -In compliance with [schema.org](https://schema.org/validFrom) `geldigop`,`geldigvan` and `geldigtot` are implemented as `validOn`,`validFrom` and `validUntil`. And can be used a query parameters on colelction operations. - -Additionally `validOn` can be used on a single object get request to get the version of that object on a given date, a 404 is returned if no version of that object can be given for that date - -Ordering results -------- -In the [zaak-api](https://zaken-api.vng.cloud/api/v1/schema/#operation/zaak_list) ordering is done in a single field parameter, we however prefer to be able to order on multiple fields in combination of ascending and descending orders. We therefore implement an order parameter as array where they key is the property on wish should be ordered and the value the type of ordering e.g. `?order[name]=desc&order[status]=asc`. The order in which the keys are added to the order array determines the order in which they are applied. - -Dutch versus English -------- -The [NL API Standard](https://geonovum.github.io/KP-APIs/#api-04-define-interfaces-in-dutch-unless-there-is-an-official-english-glossary) describes that there is a preference for Dutch in API documentation. - -> Define resources and the underlying entities, fields and so on (the information model ad the external interface) in Dutch. English is allowed in case there is an official English glossary. - -We view this as a breach with good coding practice and international coding standards, all documentation is therefore supplied in English - - - -Comma Notation versus Bracket Notation on arrays's -------- -The NL API standard uses comma notation on array's in http requests. E.g. fields=id,name,description however common browsers(based on chromium e.g. chrome and edge) use bracket notation for query style array's e.g. fields[]=id&fields[]=name,&fields[]=description. The difference of course is obvious since comma notation doesn't allow you to index arrays. [Interestingly enough there isn't actually a rfc spec for this](https://stackoverflow.com/questions/15854017/what-rfc-defines-arrays-transmitted-over-http). - -It is perceivable that in future iterations we would like to use indexed array in situations where the index of the array can't be assumed on basis of url notation, when indexes aren’t numerical, when we don’t want an index to start at 0 or when indexes are purpusly missing (comma notation of id,name,description would always refert to the equivalent of fields: [ - 0 => id, - 1 => name, - 2 => description -] - -__solution__ -We support both comma and bracket notation on array's, but only document bracket notation since it is preferred. - - -Container Setup -------- - https://medium.com/shiphp/building-a-custom-nginx-docker-image-with-environment-variables-in-the-config-4a0c36c4a617 - - -Filtering -------- -Because it is based on api-platform de proto component supports filter functions as in [api platform](https://api-platform.com/docs/core/filters/) additionally there are custom filter types available for common ground. - -__Regex Exact__ - -__Regex Contains__ - -__Like___ -The like filters is used to search for enities with the traditional sql LIKE operator. If pattern does not contain percent signs or underscores, then the pattern only represents the string itself; in that case LIKE acts like the equals operator. An underscore (_) in pattern stands for (matches) any single character; a percent sign (%) matches any sequence of zero or more characters. - -Some examples: - -'abc' LIKE 'abc' true -'abc' LIKE 'a%' true -'abc' LIKE '_b_' true -'abc' LIKE 'c' false -LIKE pattern matching always covers the entire string. Therefore, if it's desired to match a sequence anywhere within a string, the pattern must start and end with a percent sign. - -To match a literal underscore or percent sign without matching other characters, the respective character in pattern must be preceded by a backlash. - -## Kubernetes - -### Loadbalancers -We no longer provide a load balancer per component, since this would require a ip per component. Draining ip's on mult component kubernetes clusters. In stead we make componentes available as an interner service - -### server naming -A component is (speaking in kubernetes terms) a service that is available at - -## Data types - -| Period Designator | Description | -|-------------------|----------------------------------------------------------------------| -| Y | years | -| M | months | -| D | days | -| W | weeks. These get converted into days, so cannot be combined with D. | -| H | hours | -| M | minutes | -| S | seconds | - -### Types versus formats - -| Type | Format | Example | Source | Description | Documentation | -|---------|-----------|----------|--------|-------------|----------------------------------------------------------------------| -| integer | int32 | | | | | -| integer | int64 | | | | | -| string | float | 0.15625 | | | [wikipedia](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) | -| string | double | 0.15625 | | | [wikipedia](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) | -| integer | byte | | | | | -| integer | binary | | | | | -| string | date | | | | | -| string | date-time | | | | | -| string | duration | P23DT23H | | | [wikipedia](https://en.wikipedia.org/wiki/ISO_8601#Durations) | -| string | password | | | | | -| string | boolean | | | | | -| string | string | | | | | -| string | uuid | | | | | -| string | uri | | | | | -| string | email | | | | | -| string | rsin | | | | | -| string | bag | | | A BAG uuid | | -| string | bsn | | | | | -| string | iban | | | | | -| | | | | | | diff --git a/INSTALLATION.md b/INSTALLATION.md index 2f8937c6..5ed0a969 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -1,56 +1,72 @@ # Installation -This document dives a litle bit deeper into installing your component on a kubernetes cluster, looking for information on setting up your component on a lookal maschine? Take a look at the [tutorial](TUTORIAL.md) instead. +This document dives a little bit deeper into installing your component on a kubernetes cluster, looking for information on setting up your component on a local machine? Take a look at the [tutorial](TUTORIAL.md) instead. ## Setting up helm + ## Setting up tiller -Create the tiller serviceaccount: +Create the tiller service account: ```CLI $ kubectl -n kube-system create serviceaccount tiller --kubeconfig="api/helm/kubeconfig.yaml" ``` -Next, bind the tiller serviceaccount to the cluster-admin role: +Next, bind the tiller service account to the cluster-admin role: ```CLI $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller --kubeconfig="api/helm/kubeconfig.yaml" ``` Now we can run helm init, which installs Tiller on our cluster, along with some local housekeeping tasks such as downloading the stable repo details: ```CLI -$ helm init --service-account tiller --kubeconfig="api/helm/kubeconfig.yaml" +$ helm init --service-account tiller --kubeconfig="kubeconfig.yaml" ``` -To verify that Tiller is running, list the pods in thekube-system namespace: +To verify that Tiller is running, list the pods in the kube-system namespace: ```CLI -$ kubectl get pods --namespace kube-system --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl get pods --namespace kube-system --kubeconfig="kubeconfig.yaml" ``` The Tiller pod name begins with the prefix tiller-deploy-. -Now that we’ve installed both Helm components, we’re ready to use helm to install our first application. +Now that we've installed both Helm components, we're ready to use helm to install our first application. + + +## Setting up ingress +We need at least one nginx controller per kubernetes kluster, doh optionally we could set on up on a per namebase basis + +```CLI +$ helm install stable/nginx-ingress --name loadbalancer --kubeconfig="kubeconfig.yaml" +``` + +We can check that out with + +```CLI +$ kubectl describe ingress pc-dev-ingress -n=kube-system --kubeconfig="kubeconfig.yaml" +``` ## Setting up Kubernetes Dashboard -Afhter we installed helm and tiller we can easyallty use both to install kubernets dashboard +After we installed helm and tiller we can easily use both to install kubernetes dashboard + ```CLI -$ helm install stable/kubernetes-dashboard --name dashboard --kubeconfig="api/helm/kubeconfig.yaml" --namespace="kube-system" +$ helm install stable/kubernetes-dashboard --name dashboard --kubeconfig="kubeconfig.yaml" --namespace="kube-system" ``` -But before we can login to tille we need a token, we can get one of those trough the secrets. Get yourself a secret list by running the following command +But before we can login to tiller we need a token, we can get one of those trough the secrets. Get yourself a secret list by running the following command ```CLI -$ kubectl -n kube-system get secret --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl -n kube-system get secret --kubeconfig="kubeconfig.yaml" ``` -Becouse we just bound tiller to our admin acount and use tiller (trough helm) to manage our code deployment it makes sence to use the tiller token, lets look uo the tilles secret (it should loo something like "tiller-token-XXXXX" and ask for the coresponding token. +Because we just bound tiller to our admin account and use tiller (trough helm) to manage our code deployment it makes sense to use the tiller token, lets look at the tiller secret (it should look something like "tiller-token-XXXXX" and ask for the corresponding token. ```CLI -$ kubectl -n kube-system describe secrets tiller-token-5m4tg --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl -n kube-system describe secrets tiller-token-xxxxx --kubeconfig="kubeconfig.yaml" ``` This should return the token, copy it to somewhere save (just the token not the other returned information) and start up a dashboard connection ```CLI -$kubectl proxy --kubeconfig="api/helm/kubeconfig.yaml" +$ kubectl proxy --kubeconfig="kubeconfig.yaml" ``` This should proxy our dashboard to helm making it available trough our favorite browser and a simple link @@ -58,43 +74,72 @@ This should proxy our dashboard to helm making it available trough our favorite http://localhost:8001/api/v1/namespaces/kube-system/services/https:dashboard-kubernetes-dashboard:https/proxy/#!/login ``` + +## Cert Manager +https://cert-manager.io/docs/installation/kubernetes/ + +```CLI +$ kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.12/deploy/manifests/00-crds.yaml --kubeconfig="kubeconfig.yaml" +$ kubectl create namespace cert-manager --kubeconfig="kubeconfig.yaml" +``` + + The we need tp deploy the cert manager to our cluster + +```CLI +$ helm repo add jetstack https://charts.jetstack.io +$ helm install --name cert-manager --namespace cert-manager --version v0.12.0 \ jetstack/cert-manager --kubeconfig="kubeconfig.yaml" +``` + +lets check if everything is working + +```CLI +$ kubectl get pods --namespace cert-manager --kubeconfig="kubeconfig.yaml" +$ kubectl describe certificate -n dev --kubeconfig="kubeconfig.yaml" +``` + ## Deploying trough helm -First we always need to update our dependencys +First we always need to update our dependencies ```CLI $ helm dependency update ./api/helm - +``` If you want to create a new instance ```CLI -$ helm install ./api/helm --name protocomponent --kubeconfig="api/helm/kubeconfig.yaml" +$ helm install --name pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 +$ helm install --name pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 +$ helm install --name pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 ``` Or update if you want to update an existing one ```CLI -$ helm upgrade protocomponent ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" +$ helm upgrade pc-dev ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=dev --set settings.env=dev,settings.debug=1 +$ helm upgrade pc-stag ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=stag --set settings.env=stag,settings.debug=0 +$ helm upgrade pc-prod ./api/helm --kubeconfig="api/helm/kubeconfig.yaml" --namespace=prod --set settings.env=prod,settings.debug=0 ``` Or del if you want to delete an existing one ```CLI -$ helm del protocomponent --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del pc-dev --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del pc-stag --purge --kubeconfig="api/helm/kubeconfig.yaml" +$ helm del pc-prod --purge --kubeconfig="api/helm/kubeconfig.yaml" ``` -Note that you can replace commonground with the namespace that you want to use (normally the name of your component). +Note that you can replace common ground with the namespace that you want to use (normally the name of your component). ## Making your app known on NLX -The proto component commes with an default NLX setup, if you made your own component however you might want to provide it trough the [NLX](https://www.nlx.io/) service. Furntunatly the proto component commes with an nice setup for NLX integration. +The proto component comes with an default NLX setup, if you made your own component however you might want to provide it trough the [NLX](https://www.nlx.io/) service. Fortunately the proto component comes with an nice setup for NLX integration. -First of all change the nececery lines in the [.env](.env) file, basiccaly everything under the NLX setup tag. Keep in mind that you wil need to have your component available on an (sub)domain name (a simple IP wont sufice). +First of all change the necessary lines in the [.env](.env) file, basically everything under the NLX setup tag. Keep in mind that you wil need to have your component available on an (sub)domain name (a simple IP wont sufice). -To force the re-generation of certificates simply delete the org.crt en org.key in the api/nlx-setup folder +To force the re-generation of certificates simply delete the org.crt en org.key in the api/nlx-setup folder. ## Deploying trough common-ground.dev ## Setting up analytics and a help chat function -As a developer you might be intrested to know how your application documentation is used, so you can see which parts of your documentation are most read and which parts might need some additional love. You can measure this (and other user interactions) with google tag manager. Just add your google tag id to the .env file (replacing the default) under GOOGLE_TAG_MANAGER_ID. +As a developer you might be interested to know how your application documentation is used, so you can see which parts of your documentation are most read and which parts might need some additional love. You can measure this (and other user interactions) with google tag manager. Just add your google tag id to the .env file (replacing the default) under GOOGLE_TAG_MANAGER_ID. -Have you seen our sweet support-chat on the documentation page? We didn't build that ourselves ;) We use a Hubspot chat for that, just head over to Hubspot, create an account and enter your Hubspot embed code in het .env file (replacing the default) under HUBSPOT_EMBED_CODE. +Have you seen our sweet support-chat on the documentation page? We didn't build that ourselves ;). We use a Hubspot chat for that, just head over to Hubspot, create an account and enter your Hubspot embed code in het .env file (replacing the default) under HUBSPOT_EMBED_CODE. -Would you like to use a different analytics or chat-tool? Just shoot us a [feature request](https://github.com/ConductionNL/commonground-component/issues/new?assignees=&labels=&template=feature_request.md&title=New Analytics or Chat provider) +Would you like to use a different analytics or chat-tool? Just shoot us a [feature request](https://github.com/ConductionNL/commonground-component/issues/new?assignees=&labels=&template=feature_request.md&title=New%20Analytics%20or%20Chat%20provider)! diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 00000000..437766dd --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1 @@ +# Roadmap diff --git a/SECURITY.md b/SECURITY.md index 0c41cb8e..f72a06d9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,6 +1,6 @@ # SECURITY -Security of your common ground component henchmen’s on a few factors and is (in fact) for the most part provided by the common ground ecosystem. But there are definitely some steps that you should undertake yourself. We will however first briefly explain the security principles set in place so that you understand how you are being supported and what the limitation of that support is. +Security of your common ground component henchmens on a few factors and is (in fact) for the most part provided by the common ground ecosystem. But there are definitely some steps that you should undertake yourself. We will however first briefly explain the security principles set in place so that you understand how you are being supported and what the limitation of that support is. ## Codebase First of the code base, if you are extending the common ground-proto-component your code base will exist out of three parts. diff --git a/TUTORIAL.md b/TUTORIAL.md index 38e18522..d05815fc 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -1,15 +1,18 @@ # Tutorial What do you need for this tutorial? -* browser -* github account -* git client -* docker account -* docker for desktop +* Browser +* Github account +* Git client +* Docker account +* Docker for desktop + +## Before you begin +For the steps considering the generation of resources (or entities as symfony calls them) an example resource a availale, feel free to [take a look](https://github.com/ConductionNL/Proto-component-commonground/blob/master/api/src/Entity/ExampleEntity.php) at it if you have trouble figuring out the code. ## Setting up your enviroment -You can install docker-desktop from [the docker website](). +You can install docker-desktop from [the docker website](https://hub.docker.com/editions/community/docker-ce-desktop-windows). ## Generating your component (repository/codebase) @@ -23,16 +26,16 @@ After that you should be redirected to your own brand new repository. We ran a fork of the base Common Ground component, that means that we copied the code of the original project into a new repository. By doing so we made sure we have all the necessities for our component, including security and compliance with international standards. ## Spinning up your component -Before we can spin up our component we must first get a local copy from our repository, we can either do this through the command line (example here) or use a Git client. +Before we can spin up our component we must first get a local copy from our repository, we can either do this through the command line or use a Git client. -For this example where going to use GitKraken but you can use any tool you like, feel free to skip this part if you are already familiar with setting up a local clone of your repository. +For this example we're going to use GitKraken but you can use any tool you like, feel free to skip this part if you are already familiar with setting up a local clone of your repository. -Open gitkraken press "clone a repro" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repro" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branche). +Open gitkraken press "clone a repo" and fill in the form (select where on your local machine you want the repository to be stored, and fill in the link of your repository on github), press "clone a repo" and you should then see GitKraken downloading your code. After it's done press "open now" (in the box on top) and voilá your codebase (you should see an initial commit on a master branch). You can now navigate to the folder where you just installed your code, it should contain some folders and files and generally look like this. We will get into the files later, lets first spin up our component! Open a command window (example) and browse to the folder where you just stuffed your code, navigating in a command window is done by cd, so for our example we could type -cd c:\repos\common-ground\my-component (if you installed your code on a different disk then where the cmd window opens first type : for example D: and hit enter to go to that disk, D in this case). We are now in our folder, so let's go! Type docker-compose up and hit enter. From now on whenever we describe a command line command we will document it as follows: +cd c:\repos\common-ground\my-component (if you installed your code on a different disk then where the cmd window opens first type : for example D: and hit enter to go to that disk, D in this case). We are now in our folder, so let's go! Type docker-compose up and hit enter. From now on whenever we describe a command line command we will document it as follows (the $ isn't actually typed but represents your folder structure): ```CLI $ docker-compose up @@ -42,8 +45,9 @@ Your computer should now start up your local development environment. Don't worr Open your browser type as address and hit enter, you should now see your common ground component up and running. -### trouble shooting -When spinning up components we make extensive use of the cashing of docker, and use volumes to reprecent server disks. When running in to unexpected trouble always remmember to clear your local docker vm with the -a command (removing image cash) +### Trouble shooting +When spinning up components we make extensive use of the cashing of docker, and use volumes to represent server disks. When running in to unexpected trouble always remember to clear your local docker vm with the -a command (removing image cash) + ```CLI $ docker system prune -a ``` @@ -54,19 +58,19 @@ $ docker volume prune **What are we looking at?** The Common Ground base component provides a bit more than just a development interface, it also includes an example application and a backend that automatically hooks into your api. For now we're just going to focus on our api, but is good to read up on all the features of the Common Ground base component here. -## Adding your own objects -You can now access your api at http://localhost:8080/, as you can see it's pre-loaded with some example objects. Let's replace them with your own objects! +## Adding your own resources +You can now access your api at http://localhost:8080/, as you can see it's pre-loaded with some example resources. Let's replace them with your own resources! -First let's remove the objects currently in the api, we can do that by just removing the entities form our code base, navigate to the folder where you stored your code and open the folder api/src/Entity , you can find the example entities (our name for objects) there. Just delete all the php files in that folder. +First let's remove the resources currently in the api, we can do that by just removing the resources form our code base, navigate to the folder where you stored your code and open the folder api/src/Entity , you can find the example entities (the symfony name for resources) there. Just delete all the php files in that folder. -Next let's add our own entities, we can do this in two ways, we can do old fashioned coding, but we can also use the build in maker bundle of the proto component, to quickly generate our entities for us (without the fuss of actual coding). +Next let's add our own resources, we can do this in two ways, we can do old fashioned coding, but we can also use the build in maker bundle of the proto component, to quickly generate our entities for us (without the fuss of actual coding). Let's open a new command line window and navigate to our root folder, exactly like we did under "spinning up your component". And then lets fire up maker bundle (make sure that your component is still running in your other command window). We can do so by the following command: ```CLI $ docker-compose exec php bin/console make:entity ``` -We should now see a wizward that allows us to either make new entities, or add parameters to existing entities (by supplying the name of an existing entity). +We should now see a wizard that allows us to either make new entities, or add parameters to existing entities (by supplying the name of an existing resource). ## Keeping your repository up to date with the Conduction Common Ground component @@ -74,11 +78,11 @@ There are basically three reasons why you should want to keep your repository up * Security, Conduction performs regular security updates on * Functionality we strive to make regular -* Compliance, as discussions in the broader Common Ground community progress API standars might advance or change. Conduction will regularly update the Common Ground component with those changes. +* Compliance, as discussions in the broader Common Ground community progress API standards might advance or change. Conduction will regularly update the Common Ground component with those changes. Best practice is to fetch the Conduction Common Ground component into a local upstream/master branch through Git. So let's first add the original Common Ground component as an remote called upstream, and create a local branch for that remote. -__Please make sure the you have commited al your changes to your current codebase and pushed a backup copy to your Git repo before continuing__ +__Please make sure the you have committed al your changes to your current codebase and pushed a backup copy to your Git repo before continuing__ ```CLI git remote add upstream https://github.com/ConductionNL/Proto-component-commonground.git @@ -86,7 +90,7 @@ git fetch upstream git branch upstream upstream/master ``` -You can then use your favorite Git tool to merge this branch into your normal working branche without the danger of overwriting your local code. Or alternatively you can use your GIT CLI (not recommended) +You can then use your favorite Git tool to merge this branch into your normal working branch without the danger of overwriting your local code. Or alternatively you can use your GIT CLI (not recommended) ```CLI git checkout master @@ -105,43 +109,20 @@ git merge upstream --allow-unrelated-histories Keep in mind that you wil need to make sure to stay up to date about changes on the Common Ground component repository. ## Renaming your component -Right now the name of your component is 'commonground' that's thats fine while running it localy or in its own kubernetes cluster but wil get you in when running it with other components when it without using a name space. So its good practice to name your component distinctifly. But besides al of these practical reasons its of course also just cool to name your child before you unleas it on the unsuspecting commonground community. +Right now the name of your component is `commonground component` and its unique id `cg` that's that's fine while running it locally or in its own kubernetes cluster but wil get you in when running it with other components when it without using a name space. So its good practice to name your component distinctly. But besides al of these practical reasons its of course also just cool to name your child before you unleash it on the unsuspecting common ground community. -Oke, so before we can nae the component we need to come up with a name. There are a couple of conventions here. Firts of the name should tell us what the component does, or is suposede to do with one or two words. So we would normaly call an componant aboute dogs the DogComponent and one about cats te CatComponent. The second convention is that we don't usually actually name our component 'component' but indicate its position in de commonground architecture. For that we have the following options +Oke, so before we can nae the component we need to come up with a name. There are a couple of conventions here. First of the name should tell us what the component does, or is supposed to do with one or two words. So we would normally call an component about dogs the DogComponent and one about cats te CatComponent. The second convention is that we don't usually actually name our component 'component' but indicate its position in de common ground architecture. For that we have the following options: * Catalogus * RegistratieComponent * Service * Application * Tool -The we need to touch te following files +The actual name change is rather simple doh, just head over to the .env that contains all our config and change the apropriate variables * .env -* dockercompose.yaml -* api/.env -* api/helm/values.yaml -* api/docker/nginx/ -## Adding more openapi documantation - -```php -//... - /** - * @ApiProperty( - * attributes={ - * "openapi_context"={ - * "description" = "The name of a organisation", - * "type"="string", - * "format"="string", - * "example"="My Organisation" - * } - * } - * ) - */ - private $name; -//... -``` - -## Setting up security and acces (also helps with serialization) +## Setting up security and access +We want to secure our resources in such a way that only users or applications with propper right can acces and update properties. ```PHP // src/Entity/Organisation.php @@ -167,7 +148,7 @@ class Organisation ``` ## Using validation -Right now we are just accepting data and passing them on to the database, and in a mock or poc context this is fine. Most of the calls will end up being get requests anyway. But in case that we actually want our clients to make post to the api it would be wise to add some validation to the fields we are recieving. Luckely for us the component comes pre packed with a valdiation tool that we can configure from our entity through annotion. If we for example want to make a field required we could do so as follows: +Right now we are just accepting data and passing them on to the database, and in a mock or poc context this is fine. Most of the calls will end up being get requests anyway. But in case that we actually want our clients to make post to the api it would be wise to add some validation to the fields we are recieving. Luckely for us the component comes pre packed with a valdiation tool that we can configure from our resources through annotion. If we for example want to make a field required we could do so as follows: ```PHP // src/Entity/Organisation.php @@ -191,12 +172,12 @@ class Organisation Keep in mind that we need to add the assert annotation to our class dependencies under 'use'. -More inforation on using validation can be found at the [symfony website](https://symfony.com/doc/current/validation.html), but it is als worth notting that tis commonent comes pre packed with some typical NL valdidators like BSN. You can find those [here](). +More information on using validation can be found at the [symfony website](https://symfony.com/doc/current/validation.html), but it is als worth nothing that tis component comes pre packed with some typical NL validators like BSN. You can find those [here](). ## Using UUID -As default doctrine uses auto increment integers as identifiers (1,2, etc). For modern webapplications we howver prefer the use of UUID's. (e.g. e2984465-190a-4562-829e-a8cca81aa35d). Why? Wel for one it is more secure integer id's are easly gasable and make it posible to "aks" endpoint about objects that you should know about. But UUID's also have a benifit in futere proofing the application. If we in the futere want to merge a table with another table (for example becouse two organisations using a component perform a merger) then we would have to reasign al id's and relations if we where using int based id's (both tables would have a row 1,2 etc) with UUID's however the change of doubles range somwhere in the biljons. Meaning that it i likly that we oly need to either re identify only a handful of rows or more likely none at al! Turning our entire migration into a copy pase action. +As default doctrine uses auto increment integers as identifiers (1,2, etc). For modern web applications we however prefer the use of UUID's. (e.g. e2984465-190a-4562-829e-a8cca81aa35d). Why? Wel for one it is more secure integer id's are easily guessable and make it possible to "ask" endpoint about resources that you should not know about. But UUID's also have a benefit in future proofing the application. If we in the future want to merge a table with another table (for example because two organisations using a component perform a merger) then we would have to reassign al id's and relations if we where using int based id's (both tables would have a row 1,2 etc) with UUID's however the change of doubles range somewhere in the billions. Meaning that it is likely that we only need to either reidentify only a handful of rows or more likely none at al! Turning our entire migration into a copy paste action. -The proto component supports ramsy's uuid objects stratagy out of the box, so to use UUID's as intifier simply we need to add the ApiProperty as a dependecy +The proto component supports Ramsey's uuid objects strategy out of the box, so to use UUID's as identifier simply we need to add the ApiProperty as a dependency ```PHP @@ -220,20 +201,9 @@ with ```PHP //... - /** - * @var \Ramsey\Uuid\UuidInterface - * - * @ApiProperty( - * identifier=true, - * attributes={ - * "openapi_context"={ - * "description" = "The UUID identifier of this object", - * "type"="string", - * "format"="uuid", - * "example"="e2984465-190a-4562-829e-a8cca81aa35d" - * } - * } - * ) + /** + * @var \Ramsey\Uuid\UuidInterface The UUID identifier of this resource + * @example e2984465-190a-4562-829e-a8cca81aa35d * * @Groups({"read"}) * @ORM\Id @@ -245,7 +215,7 @@ with //.. ``` -and remove the integer on the getter turning this: +and remove the : ?integer on the getter turning this: ```PHP //... @@ -267,64 +237,165 @@ into this //... ``` -and your all done +and you're all done -### trouble shooting -If you have already spunn your component including your new entity your going to run into some trouble becouse doctrine is going to try changing your primary key collum (id) from an integer to string (tables tend not to like that). In that case its best to just drop your database and reinstall it using the following commands: +### Trouble shooting +If you have already spun your component including your new resource your going to run into some trouble because doctrine is going to try changing your primary key column (id) from an integer to string (tables tend not to like that). In that case its best to just drop your database and reinstall it using the following commands: ```CLI $ bin/console doctrine:schema:drop $ bin/console doctrine:schema:update --force ``` -## Datafixtures -For testing cases it can be usefull to use datafixtures a predefined set of data that fills the database of your component at startup. Since we use php classes to describe our objects creating fixtures is easy (you can find an example in your project folder at api/src/DataFixtures). We simply go trough some classes asign values and persist them to the database. Once we have written our fixtures we can use a single command to load them +## Advanced data sets + +Oke lets make it complex, until now we have just added some simple entities to our component, but what if we want to attaches one resource to another? Fortunately our build in database engine support rather complex scenarios called associations. So let [take a look](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/association-mapping.html) at that. + +Baffled? Wel its rather complex. But remember that make:entity command that we used earlier? That actually accepts relations as a data type. Or to but it simply instead of using the default 'string' we could just type "ManyToOne" and it will just fire up some questions that will help it determine how you want your relations to be. + + +### Trouble shooting +A very common error when linking entities together is circle references, those will break our serialization. Fortunately we have a need way to prevent that. Even better symfony gives us exact control of how deep we want the circular reference to go. To do this we need to use the `MaxDepth()` annotation. So lets import that + +```PHP +//... +use Symfony\Component\Serializer\Annotation\MaxDepth; +//... +``` + +And tell our serializer to use it. + +```PHP +//... +/** + * @ApiResource( + * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * ) + * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") + */ +class ExampleEntity + { +//... +``` + +We can now prevent circular references by setting a max depth on the properties causing the circular reference. +```PHP +//... + /** + * @var ArrayCollection $stuffs Some stuff that is attached to this example resource + * + * @MaxDepth(1) + * @Groups({"read","write"}) + * @ORM\ManyToOne(targetEntity="App\Entity\Stuff", inversedBy="examples") + */ + private $stuffs; +//... +``` + +## Data fixtures +For testing cases it can be useful to use data fixtures a predefined set of data that fills the database of your component at startup. Since we use php classes to describe our resources creating fixtures is easy (you can find an example in your project folder at api/src/DataFixtures). We simply go trough some classes assign values and persist them to the database. Once we have written our fixtures we can use a single command to load them ```CLI $ bin/console doctrine:fixtures:load --env=dev ``` -Be mindfull of the --env=dev here! Doctrine wil only allow fixture loading on a dev enviroment (for obvius security reasons) +Be mindful of the --env=dev here! Doctrine wil only allow fixture loading on a dev environment (for obvious security reasons) -More inforation on using datafixtures can be found at the [symfony website](https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html)(you can skipp the instalation instructions) we also enourage you to take a look at the [tabbelen component](https://github.com/ConductionNL/landelijketabellencatalogus) that makes extansive use of datafixtures. +More information on using data fixtures can be found at the [symfony website](https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html) (you can skipp the installation instructions) we also encourage you to take a look at the [tabellen component](https://github.com/ConductionNL/landelijketabellencatalogus) that makes extensive use of data fixtures. ## Sharing your work -A vital part of te common ground community is sharing your work, and telling other people what you are working. This way people can help you wiht problems that you run into. And keep tabs on any (security) updates that you make to you code. Sounds like a lot of work right? +A vital part of te common ground community is sharing your work, and telling other people what you are working. This way people can help you with problems that you run into. And keep tabs on any (security) updates that you make to you code. Sounds like a lot of work right? + +Wel it actually isn't, there is a specific common ground platform over at common-ground.dev that reads repositories and updates user. So the only thing we need to do is tell this platform that we have started a new common ground repository. How do we do that? Simple we use the name common ground (or commonground) in the discription of our repository. common-ground.dev should then pick up our repository within the hour. -Wel it actually isn't, there is a specific commonground platform over at common-gorund.dev that reads repositorys and updates user. So the only thing we need to do is tell this platform that we have started a new common ground repository. And tell it when we have updates ours. We can do all that by simply adding a webhook to our component. +Another option that we have is to declare our repository on [publiccode](), to do this you need to copy the publiccode.yaml from the [api/public/schema](api/public/schema]) folder to your root folder (dont forget to redo this every time you make a major change to your repository concerning versioning or licencing). -When using Github. To set up a webhook, go to the settings page of your repository or organization. From there, click Webhooks, then Add webhook. Use te following settings: -* Payload URL: https://www.common-ground.dev/webhook/github -* Content type: Application/JSON -* Secret: [leave blanck] -* Events: [just the push event] -Now every time you update your repository the commonground dev page will allerted, rescan your repository and do al the apropriate platform actions. It just as easy as that. +Continues integration +------- +> The following bit of the tutorial requires an additional account +> - [https://hub.docker.com/](https://hub.docker.com/) (You might already have this for docker for desktop) + +The proto component ships with a pre-fab continues integration script based on github action (there is also a travis script in here if you want it). What does this mean you ask? Continuous integration (or CI for short) is an optimized and automated way for your code to become part of your projects. In the case of your commonground component that means that we will automatically validate new code commits or pushes and (if everything checks out) build that code and deploy the containers thereof to docker hub. Making is possible to update al the environments that use those components. Whats even better is that we check your code for known security issues, so whenever a dependency or libary has a security issue you will be notified to take action. +Okay, that's nice, but how do we do that? Actually it is very simple. You do nothing. The scripts are already enabled by default. Just go to the actions tab of your github repository to see the results whenever you push code. -Automated Testing +There is however a bit of extra here that you can do and that is to insert your docker hub credentials into the repository. You can do that under the settings->secrets tab of yout repoistory by setting a `DOCKERHUB_USERNAME` and `DOCKERHUB_PASSWORD` secret containing (you might have guesed it) your dockerhub username and secret. And all done! Head over back to the code on your computer and make a small change. Then commit push that change into github. Wait for the action to complete and head over to your docker hub repository page. You should find your build containers ready for you. + +Continues deployment ------- -adasd +> The following bit of the tutorial requires an additional account +> - [https://www.digitalocean.com/](https://www.digitalocean.com/) -### Unit / Behat +Actually the repository goes a bit further then just getting your containers ready to deploy, it can acctually deploy them for you! Again all the code is already there. The only thing that you need to do is add a kubeconfig file. You can get a kubeconfig file from a running kubernetes clusters, it provides your repository with both the credentials and endpoints it needs to deploy the application. How you get a Kubeconfig file difers a bit from provider to provider. But you can get more information on that here -adas +- [Digitalocean](https://www.digitalocean.com/docs/kubernetes/how-to/connect-to-cluster/) +- [Google Cloud](https://cloud.google.com/sdk/gcloud/reference/container/clusters/get-credentials) +- [Amazone AWS](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html) -### Postman -ad +Afther you have abtained a kuneconfig you need to save it to your repository as a secret (NEVER COMMIT A KUBECONFIG FILE), use the secret `KUBECONFIG` to save your cubeconfig file. Now simply commit and push your code to your repository and presto! You have a working common-ground component online. -Audittrail +Documentation and dockblocks ------- -as +You want both your redoc documentation and your code to be readable and reausable to other developers. To this effect we use docblok annotation. You can read more about that [here](https://docs.phpdoc.org/references/phpdoc/basic-syntax.html) but the basic is this, we supply each class and propery with a docblock contained within /\* \* / characters. At the very least we want to describe our properties, the expected results and example data (see the example under [audittrail](#audittrail) -Setting up continues integration and continues delivery +Audittrail ------- -adasd +As you might expect the proto-component ships with a neat function for generating audit trails, that basically exist of three parts. + +First we need to activate logging on the entities that we want logged (for obvious security reasons we don't log resource changes by default) to do that by adding the `@Gedmo\Loggable` annotation to our php class, which should then look something like: + +```PHP +//... +/** + * @ApiResource( + * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * ) + * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") + * @Gedmo\Loggable + */ +class ExampleEntity + { +//... +``` -## Commonground specific data types +Next we need to tell the specific properties that we want to log that they are loggable (again this is a conscious choice, to prevent us from accidentally logging stuff like bsn numbers), we do that by adding the `@Gedmo\Versioned` annotation to those specific properties. That would then look something like this: +```PHP +//... + /** + * @var string $name The name of this example property + * @example My Group + * + * @Assert\NotNull + * @Assert\Length( + * max = 255 + * ) + * @Gedmo\Versioned + * @Groups({"read","write"}) + * @ORM\Column(type="string", length=255) + */ + private $name; +//... +``` -### incompleteDate +Okay actually we are now good to go, at least we are logging those things that we want logged. But.... How do we view those logs? In common ground we have a [convention](https://zaakgerichtwerken.vng.cloud/themas/achtergronddocumentatie/audit-trail) to expose a /audittrail subresource on resources that are logged. So lets add that trough our `@ApiResource` annotation. -### underInvestigation +```PHP +//... +/** + * @ApiResource( + * normalizationContext={"groups"={"read"}, "enable_max_depth"=true}, + * denormalizationContext={"groups"={"write"}, "enable_max_depth"=true} + * ) + * @ORM\Entity(repositoryClass="App\Repository\ExampleEntityRepository") + * @Gedmo\Loggable + */ +class ExampleEntity + { +//... +``` +And now we have a fully nl api strategy integrated audit trail! diff --git a/api/.env b/api/.env index a2472076..235c628f 100644 --- a/api/.env +++ b/api/.env @@ -27,8 +27,8 @@ CONDUCTION_COMMONGROUND_BAG_APIKEY=!ChangeMe! #APP_NAME='pc' APP_DESCRIPTION='Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' APP_SECRET=!ChangeMe! -TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 -TRUSTED_HOSTS='^(.+\.)?localhost|api$' +#TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +#TRUSTED_HOSTS='^(.+\.)?localhost|api$' ###< symfony/framework-bundle ### ###> symfony/framework-bundle ### diff --git a/api/Dockerfile b/api/Dockerfile index 3e02fac6..5036a777 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -29,6 +29,7 @@ RUN set -eux; \ $PHPIZE_DEPS \ icu-dev \ libzip-dev \ + libpng-dev \ postgresql-dev \ zlib-dev \ ; \ @@ -40,6 +41,8 @@ RUN set -eux; \ zip \ mysqli \ pdo_mysql \ + pcntl \ + gd \ ; \ pecl install \ apcu-${APCU_VERSION} \ @@ -80,6 +83,7 @@ ARG APP_ENV=prod # prevent the reinstallation of vendors at every changes in the source code COPY composer.json composer.lock symfony.lock ./ + RUN set -eux; \ composer install --prefer-dist --no-dev --no-scripts --no-progress --no-suggest; \ composer clear-cache @@ -102,6 +106,7 @@ RUN set -eux; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer run-script --no-dev post-install-cmd; \ chmod +x bin/console; sync + VOLUME /srv/api/var COPY docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint @@ -112,6 +117,7 @@ CMD ["php-fpm"] # Let update the docs to show the latest chages # RUN bin/console api:swagger:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 +# RUN bin/console app:publiccode:update --location=/srv/api/public/schema/ --spec-version=0.2 ############################# # "nginx" stage # @@ -119,9 +125,6 @@ CMD ["php-fpm"] # depends on the "php" stage above, and with an litle bit of help from https://github.com/shiphp/nginx-env FROM shiphp/nginx-env AS api_platform_nginx -# We use our own more secure and limited config -#ONBUILD ADD docker/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf - # Due to our config we need a copy of the public folder for serving static content COPY docker/nginx/conf.d/default.conf.template /etc/nginx/conf.d/default.conf WORKDIR /srv/api @@ -137,16 +140,17 @@ COPY --from=api_platform_php /srv/api/public public/ # "varnish" stage # ############################# # does not depend on any of the above stages, but placed here to keep everything in one Dockerfile -FROM cooptilleuls/varnish:${VARNISH_VERSION}-alpine AS api_platform_varnish -#FROM eeacms/varnish AS api_platform_varnish +#FROM cooptilleuls/varnish:${VARNISH_VERSION}-alpine AS api_platform_varnish +FROM eeacms/varnish AS api_platform_varnish #FROM varnish:6.3 AS api_platform_varnish +COPY docker/varnish/conf/default.vcl /etc/varnish/conf.d/ # Lets install envsubst -RUN apk --no-cache add gettext +#RUN apk --no-cache add gettext -COPY docker/varnish/conf /usr/local/etc/varnish/ +#COPY docker/varnish/conf /usr/local/etc/varnish/ -RUN envsubst '$PHP_SERVICE' < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl +#RUN envsubst '$PHP_SERVICE' < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl # Lets parse the toml file # RUN envsubst < /usr/local/etc/varnish/default.vcl.template > /usr/local/etc/varnish/default.vcl diff --git a/api/composer.json b/api/composer.json index 08220e05..b69f6993 100644 --- a/api/composer.json +++ b/api/composer.json @@ -8,10 +8,14 @@ "api-platform/api-pack": "^1.1", "conduction/commongroundbundle": "dev-master", "doctrine/doctrine-fixtures-bundle": "^3.2", + "doctrine/rst-parser": "^0.1.0", "guzzlehttp/guzzle": "^6.3", + "knplabs/knp-markdown-bundle": "^1.8", "lexik/jwt-authentication-bundle": "^2.6", + "phpdocumentor/reflection-docblock": "^4.3", "ramsey/uuid": "^3.8", "ramsey/uuid-doctrine": "^1.5", + "sensio/framework-extra-bundle": "^5.5", "sensiolabs/security-checker": "^6.0", "stof/doctrine-extensions-bundle": "^1.3", "symfony/console": "4.3.*", @@ -19,14 +23,15 @@ "symfony/flex": "^1.1", "symfony/framework-bundle": "4.3.*", "symfony/mercure-bundle": "*", + "symfony/property-access": "4.4.*", "symfony/yaml": "4.3.*", "tbbc/money-bundle": "^3.1", "webonyx/graphql-php": "^0.13.8" }, "require-dev" : { - "api-platform/schema-generator" : "^2.1", - "symfony/maker-bundle" : "^1.11", - "symfony/profiler-pack" : "^1.0" + "api-platform/schema-generator": "^2.1", + "symfony/maker-bundle": "^1.11", + "symfony/profiler-pack": "^1.0" }, "config" : { "preferred-install" : { @@ -58,7 +63,7 @@ "extra" : { "symfony" : { "allow-contrib" : false, - "require" : "4.3.*" + "require" : "4.4.*" } }, "scripts": { diff --git a/api/composer.lock b/api/composer.lock index 19f6628f..cbdfd079 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,28 +4,28 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f3b8b4fa5bc19705f8f77ba64ce249e5", + "content-hash": "48af4cac3c2eac2289e6cf339b11a6ea", "packages": [ { "name": "api-platform/api-pack", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/api-platform/api-pack.git", - "reference": "9e3e7421415c747e676778f211434674324dcfa9" + "reference": "41364f8763475d7709c43f790aa77a4157d038e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/api-pack/zipball/9e3e7421415c747e676778f211434674324dcfa9", - "reference": "9e3e7421415c747e676778f211434674324dcfa9", + "url": "https://api.github.com/repos/api-platform/api-pack/zipball/41364f8763475d7709c43f790aa77a4157d038e2", + "reference": "41364f8763475d7709c43f790aa77a4157d038e2", "shasum": "" }, "require": { "api-platform/core": "^2.1", "doctrine/annotations": "^1.0", - "doctrine/doctrine-bundle": "^1.6", + "doctrine/doctrine-bundle": "^1.6 || ^2.0", "doctrine/orm": "^2.4.5", - "nelmio/cors-bundle": "^1.5", + "nelmio/cors-bundle": "^1.5 || ^2.0", "php": "^7.0", "phpdocumentor/reflection-docblock": "^3.0 || ^4.0", "symfony/asset": "*", @@ -40,33 +40,34 @@ "MIT" ], "description": "A pack for API Platform", - "time": "2019-01-12T11:48:48+00:00" + "time": "2019-11-12T17:43:33+00:00" }, { "name": "api-platform/core", - "version": "v2.4.7", + "version": "v2.5.3", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "53793261113b18931ce8a9e2f174f59fdaa0c1c5" + "reference": "2d402688c485457adbc771e347e6498e70c6f232" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/53793261113b18931ce8a9e2f174f59fdaa0c1c5", - "reference": "53793261113b18931ce8a9e2f174f59fdaa0c1c5", + "url": "https://api.github.com/repos/api-platform/core/zipball/2d402688c485457adbc771e347e6498e70c6f232", + "reference": "2d402688c485457adbc771e347e6498e70c6f232", "shasum": "" }, "require": { "doctrine/inflector": "^1.0", + "fig/link-util": "^1.0", "php": ">=7.1", "psr/cache": "^1.0", "psr/container": "^1.0", - "symfony/http-foundation": "^3.4 || ^4.0", - "symfony/http-kernel": "^3.4 || ^4.0", - "symfony/property-access": "^3.4 || ^4.0", - "symfony/property-info": "^3.4 || ^4.0", - "symfony/serializer": "^4.2.6", - "symfony/web-link": "^4.1", + "symfony/http-foundation": "^4.3.6 || ^5.0", + "symfony/http-kernel": "^4.3.7 || ^5.0", + "symfony/property-access": "^3.4 || ^4.0 || ^5.0", + "symfony/property-info": "^3.4 || ^4.0 || ^5.0", + "symfony/serializer": "^4.3 || ^5.0", + "symfony/web-link": "^4.1 || ^5.0", "willdurand/negotiation": "^2.0.3" }, "conflict": { @@ -79,19 +80,20 @@ "behat/mink-browserkit-driver": "^1.3.1", "behat/mink-extension": "^2.2", "behat/symfony2-extension": "^2.1.1", - "behatch/contexts": "3.1.0", + "behatch/contexts": "^3.1.0", "doctrine/annotations": "^1.7", + "doctrine/common": "^2.11", "doctrine/data-fixtures": "^1.2.2", - "doctrine/doctrine-bundle": "^1.8", + "doctrine/doctrine-bundle": "^1.8 || ^2.0", "doctrine/doctrine-cache-bundle": "^1.3.5", - "doctrine/mongodb-odm": "^2.0@beta", - "doctrine/mongodb-odm-bundle": "^4.0@beta", - "doctrine/orm": "^2.6.3", + "doctrine/mongodb-odm": "^2.0", + "doctrine/mongodb-odm-bundle": "^4.0", + "doctrine/orm": "^2.6.4", "elasticsearch/elasticsearch": "^6.0", "friendsofsymfony/user-bundle": "^2.2@dev", "guzzlehttp/guzzle": "^6.0", "jangregor/phpstan-prophecy": "^0.4.2", - "justinrainbow/json-schema": "^5.0", + "justinrainbow/json-schema": "^5.2.1", "nelmio/api-doc-bundle": "^2.13.4", "phpdocumentor/reflection-docblock": "^3.0 || ^4.0", "phpdocumentor/type-resolver": "^0.3 || ^0.4", @@ -106,32 +108,34 @@ "ramsey/uuid": "^3.7", "ramsey/uuid-doctrine": "^1.4", "sebastian/object-enumerator": "^3.0.3", - "symfony/asset": "^3.4 || ^4.0", - "symfony/cache": "^3.4 || ^4.0", - "symfony/config": "^3.4 || ^4.0", - "symfony/console": "^3.4 || ^4.0", - "symfony/css-selector": "^3.4 || ^4.0", + "symfony/asset": "^3.4 || ^4.0 || ^5.0", + "symfony/browser-kit": "^4.3 || ^5.0", + "symfony/cache": "^3.4 || ^4.0 || ^5.0", + "symfony/config": "^3.4 || ^4.0 || ^5.0", + "symfony/console": "^3.4 || ^4.0 || ^5.0", + "symfony/css-selector": "^3.4 || ^4.0 || ^5.0", "symfony/debug": "^3.4 || ^4.0", - "symfony/dependency-injection": "^3.4 || ^4.0", - "symfony/doctrine-bridge": "^3.4 || ^4.0", - "symfony/dom-crawler": "^3.4 || ^4.0", - "symfony/event-dispatcher": "^3.4 || ^4.0", - "symfony/expression-language": "^3.4 || ^4.0", - "symfony/finder": "^3.4 || ^4.0", - "symfony/form": "^3.4 || ^4.0", - "symfony/framework-bundle": "^4.2", + "symfony/dependency-injection": "^3.4 || ^4.0 || ^5.0", + "symfony/doctrine-bridge": "^3.4 || ^4.0 || ^5.0", + "symfony/dom-crawler": "^3.4 || ^4.0 || ^5.0", + "symfony/event-dispatcher": "^3.4 || ^4.0 || ^5.0", + "symfony/expression-language": "^3.4 || ^4.0 || ^5.0", + "symfony/finder": "^3.4 || ^4.0 || ^5.0", + "symfony/form": "^3.4 || ^4.0 || ^5.0", + "symfony/framework-bundle": "^4.3.2 || ^5.0", + "symfony/http-client": "^4.3 || ^5.0", "symfony/mercure-bundle": "*", - "symfony/messenger": "^4.2", - "symfony/phpunit-bridge": "^4.3@dev", - "symfony/routing": "^3.4 || ^4.0", - "symfony/security-bundle": "^3.4 || ^4.0", - "symfony/security-core": "^3.4 || ^4.0", - "symfony/twig-bundle": "^3.4 || ^4.0", - "symfony/validator": "^3.4 || ^4.0", - "symfony/web-profiler-bundle": "^4.2", - "symfony/yaml": "^3.4 || ^4.0", - "twig/twig": "^1.41 || ^2.10", - "webonyx/graphql-php": ">=0.13 <1.0" + "symfony/messenger": "^4.3 || ^5.0", + "symfony/phpunit-bridge": "^4.3 || ^5.0", + "symfony/routing": "^3.4 || ^4.3 || ^5.0", + "symfony/security-bundle": "^3.4 || ^4.0 || ^5.0", + "symfony/security-core": "^4.3 || ^5.0", + "symfony/twig-bundle": "^3.4 || ^4.0 || ^5.0", + "symfony/validator": "^3.4 || ^4.0 || ^5.0", + "symfony/web-profiler-bundle": "^4.2 || ^5.0", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0", + "twig/twig": "^1.42.3 || ^2.12", + "webonyx/graphql-php": ">=0.13.1 <1.0" }, "suggest": { "doctrine/mongodb-odm-bundle": "To support MongoDB. Only versions 4.0 and later are supported.", @@ -184,7 +188,7 @@ "rest", "swagger" ], - "time": "2019-09-17T14:41:55+00:00" + "time": "2019-11-23T11:27:39+00:00" }, { "name": "api-platform/schema-generator", @@ -362,24 +366,24 @@ }, { "name": "composer/xdebug-handler", - "version": "1.3.3", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f" + "reference": "cbe23383749496fe0f373345208b79568e4bc248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/46867cbf8ca9fb8d60c506895449eb799db1184f", - "reference": "46867cbf8ca9fb8d60c506895449eb799db1184f", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248", + "reference": "cbe23383749496fe0f373345208b79568e4bc248", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0", + "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" }, "type": "library", "autoload": { @@ -397,12 +401,12 @@ "email": "john-stevenson@blueyonder.co.uk" } ], - "description": "Restarts a process without xdebug.", + "description": "Restarts a process without Xdebug.", "keywords": [ "Xdebug", "performance" ], - "time": "2019-05-27T17:52:04+00:00" + "time": "2019-11-06T16:40:04+00:00" }, { "name": "conduction/commongroundbundle", @@ -484,16 +488,16 @@ }, { "name": "doctrine/annotations", - "version": "v1.7.0", + "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb" + "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/fa4c4e861e809d6a1103bd620cce63ed91aedfeb", - "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/904dca4eb10715b92569fbcd79e201d5c349b6bc", + "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc", "shasum": "" }, "require": { @@ -502,7 +506,7 @@ }, "require-dev": { "doctrine/cache": "1.*", - "phpunit/phpunit": "^7.5@dev" + "phpunit/phpunit": "^7.5" }, "type": "library", "extra": { @@ -548,20 +552,20 @@ "docblock", "parser" ], - "time": "2019-08-08T18:11:40+00:00" + "time": "2019-10-01T18:55:10+00:00" }, { "name": "doctrine/cache", - "version": "v1.8.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", - "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", + "url": "https://api.github.com/repos/doctrine/cache/zipball/382e7f4db9a12dc6c19431743a2b096041bcdd62", + "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62", "shasum": "" }, "require": { @@ -572,7 +576,7 @@ }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0", "predis/predis": "~1.0" @@ -583,7 +587,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "1.9.x-dev" } }, "autoload": { @@ -596,6 +600,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -604,10 +612,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -617,26 +621,33 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "https://www.doctrine-project.org", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", "keywords": [ + "abstraction", + "apcu", "cache", - "caching" + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" ], - "time": "2018-08-21T18:01:43+00:00" + "time": "2019-11-29T15:36:20+00:00" }, { "name": "doctrine/collections", - "version": "v1.6.2", + "version": "1.6.4", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be" + "reference": "6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/c5e0bc17b1620e97c968ac409acbff28b8b850be", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7", + "reference": "6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7", "shasum": "" }, "require": { @@ -664,6 +675,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -672,10 +687,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -693,7 +704,7 @@ "iterators", "php" ], - "time": "2019-06-09T13:48:14+00:00" + "time": "2019-11-13T13:07:11+00:00" }, { "name": "doctrine/common", @@ -780,27 +791,30 @@ }, { "name": "doctrine/data-fixtures", - "version": "v1.3.2", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/data-fixtures.git", - "reference": "09b16943b27f3d80d63988d100ff256148c2f78b" + "reference": "608a35a3b5bcc4214d116603095f8b0c51091592" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/09b16943b27f3d80d63988d100ff256148c2f78b", - "reference": "09b16943b27f3d80d63988d100ff256148c2f78b", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/608a35a3b5bcc4214d116603095f8b0c51091592", + "reference": "608a35a3b5bcc4214d116603095f8b0c51091592", "shasum": "" }, "require": { - "doctrine/common": "~2.2", - "php": "^7.1" + "doctrine/common": "^2.11", + "php": "^7.2" }, "conflict": { "doctrine/phpcr-odm": "<1.3.0" }, "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^6.0", "doctrine/dbal": "^2.5.4", + "doctrine/mongodb-odm": "^1.3.0", "doctrine/orm": "^2.5.4", "phpunit/phpunit": "^7.0" }, @@ -813,7 +827,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "1.4.x-dev" } }, "autoload": { @@ -836,35 +850,34 @@ "keywords": [ "database" ], - "time": "2019-07-10T18:30:35+00:00" + "time": "2019-10-30T20:03:18+00:00" }, { "name": "doctrine/dbal", - "version": "v2.9.2", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9" + "reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", - "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/0c9a646775ef549eb0a213a4f9bd4381d9b4d934", + "reference": "0c9a646775ef549eb0a213a4f9bd4381d9b4d934", "shasum": "" }, "require": { "doctrine/cache": "^1.0", "doctrine/event-manager": "^1.0", "ext-pdo": "*", - "php": "^7.1" + "php": "^7.2" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "jetbrains/phpstorm-stubs": "^2018.1.2", - "phpstan/phpstan": "^0.10.1", - "phpunit/phpunit": "^7.4", - "symfony/console": "^2.0.5|^3.0|^4.0", - "symfony/phpunit-bridge": "^3.4.5|^4.0.5" + "doctrine/coding-standard": "^6.0", + "jetbrains/phpstorm-stubs": "^2019.1", + "phpstan/phpstan": "^0.11.3", + "phpunit/phpunit": "^8.4.1", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -875,7 +888,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.9.x-dev", + "dev-master": "2.10.x-dev", "dev-develop": "3.0.x-dev" } }, @@ -889,6 +902,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -897,10 +914,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -911,39 +924,52 @@ "keywords": [ "abstraction", "database", + "db2", "dbal", + "mariadb", + "mssql", "mysql", - "persistence", + "oci8", + "oracle", + "pdo", "pgsql", - "php", - "queryobject" - ], - "time": "2018-12-31T03:27:51+00:00" + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlanywhere", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "time": "2019-11-03T16:50:43+00:00" }, { "name": "doctrine/doctrine-bundle", - "version": "1.11.2", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "28101e20776d8fa20a00b54947fbae2db0d09103" + "reference": "0ef972d3b730f975c80db9fffa4b2a0258c91442" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/28101e20776d8fa20a00b54947fbae2db0d09103", - "reference": "28101e20776d8fa20a00b54947fbae2db0d09103", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0ef972d3b730f975c80db9fffa4b2a0258c91442", + "reference": "0ef972d3b730f975c80db9fffa4b2a0258c91442", "shasum": "" }, "require": { - "doctrine/dbal": "^2.5.12", - "doctrine/doctrine-cache-bundle": "~1.2", + "doctrine/dbal": "^2.9.0", + "doctrine/persistence": "^1.3.3", "jdorn/sql-formatter": "^1.2.16", "php": "^7.1", - "symfony/config": "^3.4|^4.1", - "symfony/console": "^3.4|^4.1", - "symfony/dependency-injection": "^3.4|^4.1", - "symfony/doctrine-bridge": "^3.4|^4.1", - "symfony/framework-bundle": "^3.4|^4.1" + "symfony/cache": "^4.3.3|^5.0", + "symfony/config": "^4.3.3|^5.0", + "symfony/console": "^3.4.30|^4.3.3|^5.0", + "symfony/dependency-injection": "^4.3.3|^5.0", + "symfony/doctrine-bridge": "^4.3.7|^5.0", + "symfony/framework-bundle": "^3.4.30|^4.3.3|^5.0", + "symfony/service-contracts": "^1.1.1|^2.0" }, "conflict": { "doctrine/orm": "<2.6", @@ -952,15 +978,15 @@ "require-dev": { "doctrine/coding-standard": "^6.0", "doctrine/orm": "^2.6", - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "7.0", - "symfony/cache": "^3.4|^4.1", + "ocramius/proxy-manager": "^2.1", + "phpunit/phpunit": "^7.5", "symfony/phpunit-bridge": "^4.2", - "symfony/property-info": "^3.4|^4.1", - "symfony/validator": "^3.4|^4.1", - "symfony/web-profiler-bundle": "^3.4|^4.1", - "symfony/yaml": "^3.4|^4.1", - "twig/twig": "^1.34|^2.4" + "symfony/property-info": "^4.3.3|^5.0", + "symfony/twig-bridge": "^3.4.30|^4.3.3|^5.0", + "symfony/validator": "^3.4.30|^4.3.3|^5.0", + "symfony/web-profiler-bundle": "^3.4.30|^4.3.3|^5.0", + "symfony/yaml": "^3.4.30|^4.3.3|^5.0", + "twig/twig": "^1.34|^2.12" }, "suggest": { "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", @@ -969,7 +995,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -983,20 +1009,20 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { - "name": "Doctrine Project", - "homepage": "http://www.doctrine-project.org/" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" } ], "description": "Symfony DoctrineBundle", @@ -1007,130 +1033,42 @@ "orm", "persistence" ], - "time": "2019-06-04T07:35:05+00:00" - }, - { - "name": "doctrine/doctrine-cache-bundle", - "version": "1.3.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/DoctrineCacheBundle.git", - "reference": "5514c90d9fb595e1095e6d66ebb98ce9ef049927" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/5514c90d9fb595e1095e6d66ebb98ce9ef049927", - "reference": "5514c90d9fb595e1095e6d66ebb98ce9ef049927", - "shasum": "" - }, - "require": { - "doctrine/cache": "^1.4.2", - "doctrine/inflector": "~1.0", - "php": ">=5.3.2", - "symfony/doctrine-bridge": "~2.7|~3.3|~4.0" - }, - "require-dev": { - "instaclick/coding-standard": "~1.1", - "instaclick/object-calisthenics-sniffs": "dev-master", - "instaclick/symfony2-coding-standard": "dev-remaster", - "phpunit/phpunit": "~4.8.36|~5.6|~6.5|~7.0", - "predis/predis": "~0.8", - "satooshi/php-coveralls": "^1.0", - "squizlabs/php_codesniffer": "~1.5", - "symfony/console": "~2.7|~3.3|~4.0", - "symfony/finder": "~2.7|~3.3|~4.0", - "symfony/framework-bundle": "~2.7|~3.3|~4.0", - "symfony/phpunit-bridge": "~2.7|~3.3|~4.0", - "symfony/security-acl": "~2.7|~3.3", - "symfony/validator": "~2.7|~3.3|~4.0", - "symfony/yaml": "~2.7|~3.3|~4.0" - }, - "suggest": { - "symfony/security-acl": "For using this bundle to cache ACLs" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Bundle\\DoctrineCacheBundle\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Fabio B. Silva", - "email": "fabio.bat.silva@gmail.com" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@hotmail.com" - }, - { - "name": "Doctrine Project", - "homepage": "http://www.doctrine-project.org/" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony Bundle for Doctrine Cache", - "homepage": "https://www.doctrine-project.org", - "keywords": [ - "cache", - "caching" - ], - "time": "2018-11-09T06:25:35+00:00" + "time": "2019-12-19T13:47:07+00:00" }, { "name": "doctrine/doctrine-fixtures-bundle", - "version": "3.2.2", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", - "reference": "90e4a4f968b2dae40e290a6ee516957af043f16c" + "reference": "8f07fcfdac7f3591f3c4bf13a50cbae05f65ed70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/90e4a4f968b2dae40e290a6ee516957af043f16c", - "reference": "90e4a4f968b2dae40e290a6ee516957af043f16c", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/8f07fcfdac7f3591f3c4bf13a50cbae05f65ed70", + "reference": "8f07fcfdac7f3591f3c4bf13a50cbae05f65ed70", "shasum": "" }, "require": { "doctrine/data-fixtures": "^1.3", - "doctrine/doctrine-bundle": "^1.6", + "doctrine/doctrine-bundle": "^1.11|^2.0", "doctrine/orm": "^2.6.0", "php": "^7.1", - "symfony/doctrine-bridge": "~3.4|^4.1", - "symfony/framework-bundle": "^3.4|^4.1" + "symfony/config": "^3.4|^4.3|^5.0", + "symfony/console": "^3.4|^4.3|^5.0", + "symfony/dependency-injection": "^3.4|^4.3|^5.0", + "symfony/doctrine-bridge": "^3.4|^4.1|^5.0", + "symfony/http-kernel": "^3.4|^4.3|^5.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", "phpunit/phpunit": "^7.4", - "symfony/phpunit-bridge": "^4.1" + "symfony/phpunit-bridge": "^4.1|^5.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "3.3.x-dev" } }, "autoload": { @@ -1144,16 +1082,16 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Doctrine Project", "homepage": "http://www.doctrine-project.org" }, { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" } ], "description": "Symfony DoctrineFixturesBundle", @@ -1162,20 +1100,20 @@ "Fixture", "persistence" ], - "time": "2019-06-12T12:03:37+00:00" + "time": "2019-11-13T15:46:58+00:00" }, { "name": "doctrine/event-manager", - "version": "v1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + "reference": "629572819973f13486371cb611386eb17851e85c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", - "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/629572819973f13486371cb611386eb17851e85c", + "reference": "629572819973f13486371cb611386eb17851e85c", "shasum": "" }, "require": { @@ -1185,7 +1123,7 @@ "doctrine/common": "<2.9@dev" }, "require-dev": { - "doctrine/coding-standard": "^4.0", + "doctrine/coding-standard": "^6.0", "phpunit/phpunit": "^7.0" }, "type": "library", @@ -1204,6 +1142,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1212,10 +1154,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1229,27 +1167,29 @@ "email": "ocramius@gmail.com" } ], - "description": "Doctrine Event Manager component", + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "keywords": [ "event", - "eventdispatcher", - "eventmanager" + "event dispatcher", + "event manager", + "event system", + "events" ], - "time": "2018-06-11T11:59:03+00:00" + "time": "2019-11-10T09:48:07+00:00" }, { "name": "doctrine/inflector", - "version": "v1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "5527a48b7313d15261292c149e55e26eae771b0a" + "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a", - "reference": "5527a48b7313d15261292c149e55e26eae771b0a", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/ec3a55242203ffa6a4b27c58176da97ff0a7aec1", + "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1", "shasum": "" }, "require": { @@ -1274,6 +1214,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1282,10 +1226,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1303,20 +1243,20 @@ "singularize", "string" ], - "time": "2018-01-09T20:05:19+00:00" + "time": "2019-10-30T19:59:35+00:00" }, { "name": "doctrine/instantiator", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "a2c590166b2133a4633738648b6b064edae0814a" + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", - "reference": "a2c590166b2133a4633738648b6b064edae0814a", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", "shasum": "" }, "require": { @@ -1359,20 +1299,20 @@ "constructor", "instantiate" ], - "time": "2019-03-17T17:37:11+00:00" + "time": "2019-10-21T16:45:58+00:00" }, { "name": "doctrine/lexer", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "e17f069ede36f7534b95adec71910ed1b49c74ea" + "reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e17f069ede36f7534b95adec71910ed1b49c74ea", - "reference": "e17f069ede36f7534b95adec71910ed1b49c74ea", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6", + "reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6", "shasum": "" }, "require": { @@ -1386,7 +1326,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -1421,38 +1361,39 @@ "parser", "php" ], - "time": "2019-07-30T19:33:28+00:00" + "time": "2019-10-30T14:39:59+00:00" }, { "name": "doctrine/orm", - "version": "v2.6.3", + "version": "v2.7.0", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "434820973cadf2da2d66e7184be370084cc32ca8" + "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/434820973cadf2da2d66e7184be370084cc32ca8", - "reference": "434820973cadf2da2d66e7184be370084cc32ca8", + "url": "https://api.github.com/repos/doctrine/orm/zipball/4d763ca4c925f647b248b9fa01b5f47aa3685d62", + "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62", "shasum": "" }, "require": { - "doctrine/annotations": "~1.5", - "doctrine/cache": "~1.6", - "doctrine/collections": "^1.4", - "doctrine/common": "^2.7.1", - "doctrine/dbal": "^2.6", - "doctrine/instantiator": "~1.1", + "doctrine/annotations": "^1.8", + "doctrine/cache": "^1.9.1", + "doctrine/collections": "^1.5", + "doctrine/common": "^2.11", + "doctrine/dbal": "^2.9.3", + "doctrine/event-manager": "^1.1", + "doctrine/instantiator": "^1.3", + "doctrine/persistence": "^1.2", "ext-pdo": "*", "php": "^7.1", - "symfony/console": "~3.0|~4.0" + "symfony/console": "^3.0|^4.0|^5.0" }, "require-dev": { - "doctrine/coding-standard": "^1.0", - "phpunit/phpunit": "^6.5", - "squizlabs/php_codesniffer": "^3.2", - "symfony/yaml": "~3.4|~4.0" + "doctrine/coding-standard": "^5.0", + "phpunit/phpunit": "^7.5", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" @@ -1463,7 +1404,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.7.x-dev" } }, "autoload": { @@ -1476,6 +1417,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1484,10 +1429,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1498,25 +1439,25 @@ } ], "description": "Object-Relational-Mapper for PHP", - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org/projects/orm.html", "keywords": [ "database", "orm" ], - "time": "2018-11-20T23:46:46+00:00" + "time": "2019-11-19T08:38:05+00:00" }, { "name": "doctrine/persistence", - "version": "1.1.1", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "3da7c9d125591ca83944f477e65ed3d7b4617c48" + "reference": "99b196bbd4715a94fa100fac664a351ffa46d6a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/3da7c9d125591ca83944f477e65ed3d7b4617c48", - "reference": "3da7c9d125591ca83944f477e65ed3d7b4617c48", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/99b196bbd4715a94fa100fac664a351ffa46d6a5", + "reference": "99b196bbd4715a94fa100fac664a351ffa46d6a5", "shasum": "" }, "require": { @@ -1531,19 +1472,20 @@ "doctrine/common": "<2.10@dev" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "phpstan/phpstan": "^0.8", + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11", "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "lib/Doctrine/Common", + "Doctrine\\Persistence\\": "lib/Doctrine/Persistence" } }, "notification-url": "https://packagist.org/downloads/", @@ -1551,6 +1493,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -1559,10 +1505,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -1585,7 +1527,7 @@ "orm", "persistence" ], - "time": "2019-04-23T08:28:24+00:00" + "time": "2019-12-13T10:43:02+00:00" }, { "name": "doctrine/reflection", @@ -1662,6 +1604,69 @@ ], "time": "2018-06-14T14:45:07+00:00" }, + { + "name": "doctrine/rst-parser", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/rst-parser.git", + "reference": "49ea41cf15b93c4ac493df3f05c49999ef661cd4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/rst-parser/zipball/49ea41cf15b93c4ac493df3f05c49999ef661cd4", + "reference": "49ea41cf15b93c4ac493df3f05c49999ef661cd4", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^1.0", + "php": "^7.1", + "symfony/filesystem": "^4.1", + "twig/twig": "^2.5" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "gajus/dindent": "^2.0.2", + "phpstan/phpstan": "^0.10", + "phpstan/phpstan-deprecation-rules": "^0.10", + "phpstan/phpstan-phpunit": "^0.10", + "phpstan/phpstan-strict-rules": "^0.10", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\RST\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Passault", + "email": "g.passault@gmail.com", + "homepage": "http://www.gregwar.com/" + }, + { + "name": "Jonathan H. Wage", + "email": "jonwage@gmail.com", + "homepage": "https://jwage.com" + } + ], + "description": "PHP library to parse reStructuredText documents and generate HTML or LaTeX documents.", + "homepage": "https://github.com/doctrine/rst-parser", + "keywords": [ + "html", + "latex", + "markup", + "parser", + "reStructuredText", + "rst" + ], + "time": "2019-04-15T19:55:14+00:00" + }, { "name": "easyrdf/easyrdf", "version": "0.9.1", @@ -1726,22 +1731,25 @@ }, { "name": "fig/link-util", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/link-util.git", - "reference": "1a07821801a148be4add11ab0603e4af55a72fac" + "reference": "47f55860678a9e202206047bc02767556d298106" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/link-util/zipball/1a07821801a148be4add11ab0603e4af55a72fac", - "reference": "1a07821801a148be4add11ab0603e4af55a72fac", + "url": "https://api.github.com/repos/php-fig/link-util/zipball/47f55860678a9e202206047bc02767556d298106", + "reference": "47f55860678a9e202206047bc02767556d298106", "shasum": "" }, "require": { "php": ">=5.5.0", "psr/link": "~1.0@dev" }, + "provide": { + "psr/link-implementation": "1.0" + }, "require-dev": { "phpunit/phpunit": "^5.1", "squizlabs/php_codesniffer": "^2.3.1" @@ -1776,20 +1784,20 @@ "psr-13", "rest" ], - "time": "2016-10-17T18:31:11+00:00" + "time": "2019-12-18T15:40:05+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.15.3", + "version": "v2.16.1", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "705490b0f282f21017d73561e9498d2b622ee34c" + "reference": "c8afb599858876e95e8ebfcd97812d383fa23f02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/705490b0f282f21017d73561e9498d2b622ee34c", - "reference": "705490b0f282f21017d73561e9498d2b622ee34c", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/c8afb599858876e95e8ebfcd97812d383fa23f02", + "reference": "c8afb599858876e95e8ebfcd97812d383fa23f02", "shasum": "" }, "require": { @@ -1800,15 +1808,15 @@ "ext-tokenizer": "*", "php": "^5.6 || ^7.0", "php-cs-fixer/diff": "^1.3", - "symfony/console": "^3.4.17 || ^4.1.6", - "symfony/event-dispatcher": "^3.0 || ^4.0", - "symfony/filesystem": "^3.0 || ^4.0", - "symfony/finder": "^3.0 || ^4.0", - "symfony/options-resolver": "^3.0 || ^4.0", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0", + "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", + "symfony/finder": "^3.0 || ^4.0 || ^5.0", + "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", "symfony/polyfill-php70": "^1.0", "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0", - "symfony/stopwatch": "^3.0 || ^4.0" + "symfony/process": "^3.0 || ^4.0 || ^5.0", + "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", @@ -1821,8 +1829,8 @@ "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", "phpunitgoodpractices/traits": "^1.8", - "symfony/phpunit-bridge": "^4.3", - "symfony/yaml": "^3.0 || ^4.0" + "symfony/phpunit-bridge": "^4.3 || ^5.0", + "symfony/yaml": "^3.0 || ^4.0 || ^5.0" }, "suggest": { "ext-mbstring": "For handling non-UTF8 characters in cache signature.", @@ -1865,20 +1873,20 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2019-08-31T12:51:54+00:00" + "time": "2019-11-25T22:10:32+00:00" }, { "name": "gedmo/doctrine-extensions", - "version": "v2.4.37", + "version": "v2.4.38", "source": { "type": "git", "url": "https://github.com/Atlantic18/DoctrineExtensions.git", - "reference": "5dd471f656e46d815f063bf3f12c667649ec7ffb" + "reference": "81681364331b131518060e4776300a5346df1eb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/5dd471f656e46d815f063bf3f12c667649ec7ffb", - "reference": "5dd471f656e46d815f063bf3f12c667649ec7ffb", + "url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/81681364331b131518060e4776300a5346df1eb5", + "reference": "81681364331b131518060e4776300a5346df1eb5", "shasum": "" }, "require": { @@ -1887,14 +1895,15 @@ "php": ">=5.3.2" }, "conflict": { - "doctrine/annotations": "<1.2" + "doctrine/annotations": "<1.2", + "doctrine/mongodb-odm": ">=2.0" }, "require-dev": { "doctrine/common": ">=2.5.0", - "doctrine/mongodb-odm": ">=1.0.2", + "doctrine/mongodb-odm": ">=1.0.2 <2.0", "doctrine/orm": ">=2.5.0", - "phpunit/phpunit": "^4.8.35|^5.7|^6.5", - "symfony/yaml": "~2.6|~3.0|~4.0" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "symfony/yaml": "~2.6 || ~3.0 || ~4.0" }, "suggest": { "doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM", @@ -1916,10 +1925,6 @@ "MIT" ], "authors": [ - { - "name": "David Buchmann", - "email": "david@liip.ch" - }, { "name": "Gediminas Morkevicius", "email": "gediminas.morkevicius@gmail.com" @@ -1927,6 +1932,10 @@ { "name": "Gustavo Falco", "email": "comfortablynumb84@gmail.com" + }, + { + "name": "David Buchmann", + "email": "david@liip.ch" } ], "description": "Doctrine2 behavioral extensions", @@ -1946,48 +1955,50 @@ "tree", "uploadable" ], - "time": "2019-03-17T18:16:12+00:00" + "time": "2019-11-08T22:33:07+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.3.3", + "version": "6.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", + "reference": "43ece0e75098b7ecd8d13918293029e555a50f82", "shasum": "" }, "require": { + "ext-json": "*", "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", + "guzzlehttp/psr7": "^1.6.1", "php": ">=5.5" }, "require-dev": { "ext-curl": "*", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.0" + "psr/log": "^1.1" }, "suggest": { + "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.3-dev" + "dev-master": "6.5-dev" } }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\": "src/" - } + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2011,7 +2022,7 @@ "rest", "web service" ], - "time": "2018-04-22T15:46:56+00:00" + "time": "2019-12-23T11:57:10+00:00" }, { "name": "guzzlehttp/promises", @@ -2186,32 +2197,95 @@ "time": "2014-01-12T16:20:24+00:00" }, { - "name": "lcobucci/jwt", - "version": "3.3.1", + "name": "knplabs/knp-markdown-bundle", + "version": "1.8.1", "source": { "type": "git", - "url": "https://github.com/lcobucci/jwt.git", - "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18" + "url": "https://github.com/KnpLabs/KnpMarkdownBundle.git", + "reference": "7238cc264eab9c42d1a5b71950b55fe3dd78ab38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/a11ec5f4b4d75d1fcd04e133dede4c317aac9e18", - "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18", + "url": "https://api.github.com/repos/KnpLabs/KnpMarkdownBundle/zipball/7238cc264eab9c42d1a5b71950b55fe3dd78ab38", + "reference": "7238cc264eab9c42d1a5b71950b55fe3dd78ab38", "shasum": "" }, "require": { - "ext-mbstring": "*", - "ext-openssl": "*", - "php": "^5.6 || ^7.0" + "michelf/php-markdown": "~1.4", + "php": "^7.1.3", + "symfony/dependency-injection": "~3.4|^4.0|^5.0", + "symfony/framework-bundle": "~3.4|^4.0|^5.0" }, "require-dev": { - "mikey179/vfsstream": "~1.5", - "phpmd/phpmd": "~2.2", - "phpunit/php-invoker": "~1.1", - "phpunit/phpunit": "^5.7 || ^7.3", - "squizlabs/php_codesniffer": "~2.3" + "symfony/phpunit-bridge": "^4.4.0 || ^5.0", + "symfony/templating": "~3.4|^4.0|^5.0" }, - "type": "library", + "suggest": { + "ext-sundown": "to use optional support for php-sundown extension instead of php implementation", + "symfony/twig-bundle": "to use the Twig markdown filter" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Knp\\Bundle\\MarkdownBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KnpLabs Team", + "homepage": "http://knplabs.com" + }, + { + "name": "Symfony Community", + "homepage": "http://github.com/KnpLabs/KnpMarkdownBundle/contributors" + } + ], + "description": "Knplabs markdown bundle transforms markdown into html", + "homepage": "http://github.com/KnpLabs/KnpMarkdownBundle", + "keywords": [ + "bundle", + "knp", + "knplabs", + "markdown" + ], + "time": "2019-11-26T13:18:52+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "3.3.1", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/a11ec5f4b4d75d1fcd04e133dede4c317aac9e18", + "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-openssl": "*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "mikey179/vfsstream": "~1.5", + "phpmd/phpmd": "~2.2", + "phpunit/php-invoker": "~1.1", + "phpunit/phpunit": "^5.7 || ^7.3", + "squizlabs/php_codesniffer": "~2.3" + }, + "type": "library", "extra": { "branch-alias": { "dev-master": "3.1-dev" @@ -2242,16 +2316,16 @@ }, { "name": "league/html-to-markdown", - "version": "4.8.2", + "version": "4.9.0", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "e747489191f8e9144a7270eb61f8b9516e99e413" + "reference": "71319108e3db506250b8987721b13568fd9fa446" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/e747489191f8e9144a7270eb61f8b9516e99e413", - "reference": "e747489191f8e9144a7270eb61f8b9516e99e413", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/71319108e3db506250b8987721b13568fd9fa446", + "reference": "71319108e3db506250b8987721b13568fd9fa446", "shasum": "" }, "require": { @@ -2261,7 +2335,7 @@ }, "require-dev": { "mikehaertl/php-shellcommand": "~1.1.0", - "phpunit/phpunit": "4.*", + "phpunit/phpunit": "^4.8|^5.7", "scrutinizer/ocular": "~1.1" }, "bin": [ @@ -2270,7 +2344,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "4.10-dev" } }, "autoload": { @@ -2302,20 +2376,20 @@ "html", "markdown" ], - "time": "2019-08-02T11:57:39+00:00" + "time": "2019-11-02T14:54:14+00:00" }, { "name": "lexik/jwt-authentication-bundle", - "version": "v2.6.4", + "version": "v2.6.5", "source": { "type": "git", "url": "https://github.com/lexik/LexikJWTAuthenticationBundle.git", - "reference": "f79f20b282834878aab10530ca102a80396624ed" + "reference": "448551fc08c6cff37aad9d8f27f6b9615cd28966" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/f79f20b282834878aab10530ca102a80396624ed", - "reference": "f79f20b282834878aab10530ca102a80396624ed", + "url": "https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/448551fc08c6cff37aad9d8f27f6b9615cd28966", + "reference": "448551fc08c6cff37aad9d8f27f6b9615cd28966", "shasum": "" }, "require": { @@ -2323,17 +2397,16 @@ "lcobucci/jwt": "^3.2", "namshi/jose": "^7.2", "php": "^5.5|^7.0", - "symfony/framework-bundle": "^3.4|^4.0", - "symfony/security-bundle": "^3.4|^4.0" + "symfony/framework-bundle": "^3.4|^4.0|^5.0", + "symfony/security-bundle": "^3.4|^4.0|^5.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^1.1|^2.8", - "symfony/browser-kit": "^3.4|^4.0", - "symfony/console": "^3.4|^4.0", - "symfony/dom-crawler": "^3.4|^4.0", - "symfony/phpunit-bridge": "^3.4|^4.0", - "symfony/var-dumper": "^3.4|^4.0", - "symfony/yaml": "^3.4|^4.0" + "symfony/browser-kit": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dom-crawler": "^3.4|^4.0|^5.0", + "symfony/phpunit-bridge": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "gesdinet/jwt-refresh-token-bundle": "Implements a refresh token system over Json Web Tokens in Symfony", @@ -2399,7 +2472,56 @@ "rest", "symfony" ], - "time": "2019-07-29T10:02:31+00:00" + "time": "2019-11-22T14:22:26+00:00" + }, + { + "name": "michelf/php-markdown", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-markdown.git", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/c83178d49e372ca967d1a8c77ae4e051b3a3c75c", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">=4.3 <5.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Michelf\\": "Michelf/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ], + "time": "2019-12-02T02:32:27+00:00" }, { "name": "moneyphp/money", @@ -2521,30 +2643,29 @@ }, { "name": "nelmio/cors-bundle", - "version": "1.5.6", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioCorsBundle.git", - "reference": "10a24c10f242440211ed31075e74f81661c690d9" + "reference": "9683e6d30d000ef998919261329d825de7c53499" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/10a24c10f242440211ed31075e74f81661c690d9", - "reference": "10a24c10f242440211ed31075e74f81661c690d9", + "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/9683e6d30d000ef998919261329d825de7c53499", + "reference": "9683e6d30d000ef998919261329d825de7c53499", "shasum": "" }, "require": { - "symfony/framework-bundle": "^2.7 || ^3.0 || ^4.0" + "symfony/framework-bundle": "^4.3 || ^5.0" }, "require-dev": { - "matthiasnoback/symfony-dependency-injection-test": "^1.0 || ^2.0", - "mockery/mockery": "^0.9 || ^1.0", - "symfony/phpunit-bridge": "^2.7 || ^3.0 || ^4.0" + "mockery/mockery": "^1.2", + "symfony/phpunit-bridge": "^4.3 || ^5.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.5.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -2569,26 +2690,26 @@ "homepage": "https://github.com/nelmio/NelmioCorsBundle/contributors" } ], - "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony2 application", + "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony application", "keywords": [ "api", "cors", "crossdomain" ], - "time": "2019-06-17T08:53:14+00:00" + "time": "2019-11-15T08:54:08+00:00" }, { "name": "nikic/php-parser", - "version": "v4.2.4", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4" + "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/97e59c7a16464196a8b9c77c47df68e4a39a45c4", - "reference": "97e59c7a16464196a8b9c77c47df68e4a39a45c4", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/9a9981c347c5c49d6dfe5cf826bb882b824080dc", + "reference": "9a9981c347c5c49d6dfe5cf826bb882b824080dc", "shasum": "" }, "require": { @@ -2596,6 +2717,7 @@ "php": ">=7.0" }, "require-dev": { + "ircmaxell/php-yacc": "0.0.5", "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" }, "bin": [ @@ -2604,7 +2726,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -2626,7 +2748,7 @@ "parser", "php" ], - "time": "2019-09-01T07:51:21+00:00" + "time": "2019-11-08T13:50:10+00:00" }, { "name": "php-cs-fixer/diff", @@ -2733,16 +2855,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", + "version": "4.3.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" + "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", + "reference": "2ecaa9fef01634c83bfa8dc1fe35fb5cef223a62", "shasum": "" }, "require": { @@ -2780,7 +2902,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" + "time": "2019-12-20T13:40:23+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -3112,44 +3234,46 @@ }, { "name": "ramsey/uuid", - "version": "3.8.0", + "version": "3.9.2", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3" + "reference": "7779489a47d443f845271badbdcedfe4df8e06fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/d09ea80159c1929d75b3f9c60504d613aeb4a1e3", - "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/7779489a47d443f845271badbdcedfe4df8e06fb", + "reference": "7779489a47d443f845271badbdcedfe4df8e06fb", "shasum": "" }, "require": { - "paragonie/random_compat": "^1.0|^2.0|9.99.99", - "php": "^5.4 || ^7.0", + "ext-json": "*", + "paragonie/random_compat": "^1 | ^2 | 9.99.99", + "php": "^5.4 | ^7 | ^8", "symfony/polyfill-ctype": "^1.8" }, "replace": { "rhumsaa/uuid": "self.version" }, "require-dev": { - "codeception/aspect-mock": "^1.0 | ~2.0.0", - "doctrine/annotations": "~1.2.0", - "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ~2.1.0", - "ircmaxell/random-lib": "^1.1", - "jakub-onderka/php-parallel-lint": "^0.9.0", - "mockery/mockery": "^0.9.9", + "codeception/aspect-mock": "^1 | ^2", + "doctrine/annotations": "^1.2", + "goaop/framework": "1.0.0-alpha.2 | ^1 | ^2.1", + "jakub-onderka/php-parallel-lint": "^1", + "mockery/mockery": "^0.9.11 | ^1", "moontoast/math": "^1.1", - "php-mock/php-mock-phpunit": "^0.3|^1.1", - "phpunit/phpunit": "^4.7|^5.0|^6.5", - "squizlabs/php_codesniffer": "^2.3" + "paragonie/random-lib": "^2", + "php-mock/php-mock-phpunit": "^0.3 | ^1.1", + "phpunit/phpunit": "^4.8 | ^5.4 | ^6.5", + "squizlabs/php_codesniffer": "^3.5" }, "suggest": { "ext-ctype": "Provides support for PHP Ctype functions", "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-openssl": "Provides the OpenSSL extension for use with the OpenSslGenerator", "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", - "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, @@ -3162,13 +3286,21 @@ "autoload": { "psr-4": { "Ramsey\\Uuid\\": "src/" - } + }, + "files": [ + "src/functions.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + }, { "name": "Marijn Huizendveld", "email": "marijn.huizendveld@gmail.com" @@ -3176,11 +3308,6 @@ { "name": "Thibaud Fabre", "email": "thibaud@aztech.io" - }, - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" } ], "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", @@ -3190,7 +3317,7 @@ "identifier", "uuid" ], - "time": "2018-07-19T23:38:55+00:00" + "time": "2019-12-17T08:18:51+00:00" }, { "name": "ramsey/uuid-doctrine", @@ -3249,6 +3376,84 @@ ], "time": "2018-08-11T21:01:22+00:00" }, + { + "name": "sensio/framework-extra-bundle", + "version": "v5.5.2", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", + "reference": "92acfcc610e2180c52790ec3ff2e893f67e76b32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/92acfcc610e2180c52790ec3ff2e893f67e76b32", + "reference": "92acfcc610e2180c52790ec3ff2e893f67e76b32", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "php": ">=7.1.3", + "symfony/config": "^4.3|^5.0", + "symfony/dependency-injection": "^4.3|^5.0", + "symfony/framework-bundle": "^4.3|^5.0", + "symfony/http-kernel": "^4.3|^5.0" + }, + "conflict": { + "doctrine/doctrine-cache-bundle": "<1.3.1" + }, + "require-dev": { + "doctrine/doctrine-bundle": "^1.11|^2.0", + "doctrine/orm": "^2.5", + "nyholm/psr7": "^1.1", + "symfony/browser-kit": "^4.3|^5.0", + "symfony/dom-crawler": "^4.3|^5.0", + "symfony/expression-language": "^4.3|^5.0", + "symfony/finder": "^4.3|^5.0", + "symfony/monolog-bridge": "^4.0|^5.0", + "symfony/monolog-bundle": "^3.2", + "symfony/phpunit-bridge": "^4.3.5|^5.0", + "symfony/psr-http-message-bridge": "^1.1", + "symfony/security-bundle": "^4.3|^5.0", + "symfony/twig-bundle": "^4.3|^5.0", + "symfony/yaml": "^4.3|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "suggest": { + "symfony/expression-language": "", + "symfony/psr-http-message-bridge": "To use the PSR-7 converters", + "symfony/security-bundle": "" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "5.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sensio\\Bundle\\FrameworkExtraBundle\\": "src/" + }, + "exclude-from-classmap": [ + "/tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": [ + "annotations", + "controllers" + ], + "time": "2019-12-12T16:21:49+00:00" + }, { "name": "sensiolabs/security-checker", "version": "v6.0.3", @@ -3364,24 +3569,24 @@ }, { "name": "symfony/asset", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "3f97e57596884f7b9158d564a533112a0d19dbdd" + "reference": "7ec5fc653dab63d7519a6f411982ee224a696d66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/3f97e57596884f7b9158d564a533112a0d19dbdd", - "reference": "3f97e57596884f7b9158d564a533112a0d19dbdd", + "url": "https://api.github.com/repos/symfony/asset/zipball/7ec5fc653dab63d7519a6f411982ee224a696d66", + "reference": "7ec5fc653dab63d7519a6f411982ee224a696d66", "shasum": "" }, "require": { "php": "^7.1.3" }, "require-dev": { - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "~3.4|~4.0" + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/http-foundation": "" @@ -3389,7 +3594,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3416,34 +3621,35 @@ ], "description": "Symfony Asset Component", "homepage": "https://symfony.com", - "time": "2019-08-03T21:50:52+00:00" + "time": "2019-10-12T00:35:04+00:00" }, { "name": "symfony/cache", - "version": "v4.3.9", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "2a7bcc592adcaab9efc165bbced5a91fe905fad4" + "reference": "6af64bab165e588300378a87bcd2df3c7c31c144" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/2a7bcc592adcaab9efc165bbced5a91fe905fad4", - "reference": "2a7bcc592adcaab9efc165bbced5a91fe905fad4", + "url": "https://api.github.com/repos/symfony/cache/zipball/6af64bab165e588300378a87bcd2df3c7c31c144", + "reference": "6af64bab165e588300378a87bcd2df3c7c31c144", "shasum": "" }, "require": { "php": "^7.1.3", "psr/cache": "~1.0", "psr/log": "~1.0", - "symfony/cache-contracts": "^1.1", - "symfony/service-contracts": "^1.1", - "symfony/var-exporter": "^4.2" + "symfony/cache-contracts": "^1.1.7|^2", + "symfony/service-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.2|^5.0" }, "conflict": { "doctrine/dbal": "<2.5", "symfony/dependency-injection": "<3.4", - "symfony/var-dumper": "<3.4" + "symfony/http-kernel": "<4.4", + "symfony/var-dumper": "<4.4" }, "provide": { "psr/cache-implementation": "1.0", @@ -3456,14 +3662,14 @@ "doctrine/dbal": "~2.5", "predis/predis": "~1.1", "psr/simple-cache": "^1.0", - "symfony/config": "~4.2", - "symfony/dependency-injection": "~3.4|~4.1", - "symfony/var-dumper": "^4.1.1" + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.1|^5.0", + "symfony/var-dumper": "^4.4|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3494,7 +3700,7 @@ "caching", "psr6" ], - "time": "2019-12-01T10:50:31+00:00" + "time": "2019-12-16T10:45:21+00:00" }, { "name": "symfony/cache-contracts", @@ -3556,32 +3762,32 @@ }, { "name": "symfony/config", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece" + "reference": "6911d432edd5b50822986604fd5a5be3af856d30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/07d49c0f823e0bc367c6d84e35b61419188a5ece", - "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece", + "url": "https://api.github.com/repos/symfony/config/zipball/6911d432edd5b50822986604fd5a5be3af856d30", + "reference": "6911d432edd5b50822986604fd5a5be3af856d30", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/filesystem": "~3.4|~4.0", + "symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/finder": "<3.4" }, "require-dev": { - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/messenger": "~4.1", - "symfony/yaml": "~3.4|~4.0" + "symfony/event-dispatcher": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/messenger": "^4.1|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -3589,7 +3795,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3616,7 +3822,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-18T12:00:29+00:00" }, { "name": "symfony/console", @@ -3766,16 +3972,16 @@ }, { "name": "symfony/debug", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "b8600a1d7d20b0e80906398bb1f50612fa074a8e" + "reference": "5c4c1db977dc70bb3250e1308d3e8c6341aa38f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/b8600a1d7d20b0e80906398bb1f50612fa074a8e", - "reference": "b8600a1d7d20b0e80906398bb1f50612fa074a8e", + "url": "https://api.github.com/repos/symfony/debug/zipball/5c4c1db977dc70bb3250e1308d3e8c6341aa38f5", + "reference": "5c4c1db977dc70bb3250e1308d3e8c6341aa38f5", "shasum": "" }, "require": { @@ -3818,29 +4024,29 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2019-11-28T13:33:56+00:00" + "time": "2019-12-16T14:46:54+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9" + "reference": "79b0358207a3571cc3af02a57d0321927921f539" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d3ad14b66ac773ba6123622eb9b5b010165fe3d9", - "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/79b0358207a3571cc3af02a57d0321927921f539", + "reference": "79b0358207a3571cc3af02a57d0321927921f539", "shasum": "" }, "require": { "php": "^7.1.3", "psr/container": "^1.0", - "symfony/service-contracts": "^1.1.6" + "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { - "symfony/config": "<4.3", + "symfony/config": "<4.3|>=5.0", "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", "symfony/yaml": "<3.4" @@ -3851,8 +4057,8 @@ }, "require-dev": { "symfony/config": "^4.3", - "symfony/expression-language": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/config": "", @@ -3864,7 +4070,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3891,35 +4097,38 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-08-26T16:27:33+00:00" + "time": "2019-12-19T16:00:02+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "d2967b2b43788bd3a7cddeb8bd4567e142b3821c" + "reference": "3e40beb8dbb06d2967e37938f4c3f20f425137a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/d2967b2b43788bd3a7cddeb8bd4567e142b3821c", - "reference": "d2967b2b43788bd3a7cddeb8bd4567e142b3821c", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/3e40beb8dbb06d2967e37938f4c3f20f425137a6", + "reference": "3e40beb8dbb06d2967e37938f4c3f20f425137a6", "shasum": "" }, "require": { "doctrine/event-manager": "~1.0", - "doctrine/persistence": "~1.0", + "doctrine/persistence": "^1.3", "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1" + "symfony/service-contracts": "^1.1|^2" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/dependency-injection": "<3.4", - "symfony/form": "<4.3", - "symfony/messenger": "<4.3" + "symfony/form": "<4.4", + "symfony/http-kernel": "<4.3.7", + "symfony/messenger": "<4.3", + "symfony/security-core": "<4.4", + "symfony/validator": "<4.4.2|<5.0.2,>=5.0" }, "require-dev": { "doctrine/annotations": "~1.7", @@ -3929,19 +4138,20 @@ "doctrine/dbal": "~2.4", "doctrine/orm": "^2.6.3", "doctrine/reflection": "~1.0", - "symfony/config": "^4.2", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/form": "~4.3", - "symfony/http-kernel": "~3.4|~4.0", - "symfony/messenger": "~4.3", - "symfony/property-access": "~3.4|~4.0", - "symfony/property-info": "~3.4|~4.0", - "symfony/proxy-manager-bridge": "~3.4|~4.0", - "symfony/security-core": "~3.4|~4.0", - "symfony/stopwatch": "~3.4|~4.0", - "symfony/translation": "~3.4|~4.0", - "symfony/validator": "^3.4.31|^4.3.4" + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/form": "^4.4|^5.0", + "symfony/http-kernel": "^4.3.7", + "symfony/messenger": "^4.4|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/property-info": "^3.4|^4.0|^5.0", + "symfony/proxy-manager-bridge": "^3.4|^4.0|^5.0", + "symfony/security-core": "^4.4|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/translation": "^3.4|^4.0|^5.0", + "symfony/validator": "^4.4.2|^5.0.2", + "symfony/var-dumper": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/data-fixtures": "", @@ -3954,7 +4164,7 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -3981,20 +4191,20 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com", - "time": "2019-08-26T11:29:20+00:00" + "time": "2019-12-17T08:15:02+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "cc686552948d627528c0e2e759186dff67c2610e" + "reference": "36bbcab9369fc2f583220890efd43bf262d563fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/cc686552948d627528c0e2e759186dff67c2610e", - "reference": "cc686552948d627528c0e2e759186dff67c2610e", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/36bbcab9369fc2f583220890efd43bf262d563fd", + "reference": "36bbcab9369fc2f583220890efd43bf262d563fd", "shasum": "" }, "require": { @@ -4007,7 +4217,7 @@ }, "require-dev": { "masterminds/html5": "^2.6", - "symfony/css-selector": "~3.4|~4.0" + "symfony/css-selector": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/css-selector": "" @@ -4015,7 +4225,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4042,7 +4252,7 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-10-29T11:38:30+00:00" }, { "name": "symfony/dotenv", @@ -4101,9 +4311,65 @@ ], "time": "2019-08-03T21:50:52+00:00" }, + { + "name": "symfony/error-handler", + "version": "v4.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "6d7d7712a6ff5215ec26215672293b154f1db8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/6d7d7712a6ff5215ec26215672293b154f1db8c1", + "reference": "6d7d7712a6ff5215ec26215672293b154f1db8c1", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/log": "~1.0", + "symfony/debug": "^4.4", + "symfony/var-dumper": "^4.4|^5.0" + }, + "require-dev": { + "symfony/http-kernel": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ErrorHandler Component", + "homepage": "https://symfony.com", + "time": "2019-12-16T14:46:54+00:00" + }, { "name": "symfony/event-dispatcher", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -4231,27 +4497,27 @@ }, { "name": "symfony/expression-language", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "c8b47d8820d3bf75f757eec8a2647584c14cf0c6" + "reference": "539e7ff0b635c8b90d8127bc929da781a96eab2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/c8b47d8820d3bf75f757eec8a2647584c14cf0c6", - "reference": "c8b47d8820d3bf75f757eec8a2647584c14cf0c6", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/539e7ff0b635c8b90d8127bc929da781a96eab2d", + "reference": "539e7ff0b635c8b90d8127bc929da781a96eab2d", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/cache": "~3.4|~4.0", - "symfony/service-contracts": "^1.1" + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4278,20 +4544,20 @@ ], "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com", - "time": "2019-08-08T09:29:19+00:00" + "time": "2019-12-10T10:33:21+00:00" }, { "name": "symfony/filesystem", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263" + "reference": "40c2606131d56eff6f193b6e2ceb92414653b591" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/9abbb7ef96a51f4d7e69627bc6f63307994e4263", - "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/40c2606131d56eff6f193b6e2ceb92414653b591", + "reference": "40c2606131d56eff6f193b6e2ceb92414653b591", "shasum": "" }, "require": { @@ -4301,7 +4567,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4328,20 +4594,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-08-20T14:07:54+00:00" + "time": "2019-11-26T23:16:41+00:00" }, { "name": "symfony/finder", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2" + "reference": "ce8743441da64c41e2a667b8eb66070444ed911e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/86c1c929f0a4b24812e1eb109262fc3372c8e9f2", - "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2", + "url": "https://api.github.com/repos/symfony/finder/zipball/ce8743441da64c41e2a667b8eb66070444ed911e", + "reference": "ce8743441da64c41e2a667b8eb66070444ed911e", "shasum": "" }, "require": { @@ -4350,7 +4616,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4377,20 +4643,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-08-14T12:26:46+00:00" + "time": "2019-11-17T21:56:56+00:00" }, { "name": "symfony/flex", - "version": "v1.4.6", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "133e649fdf08aeb8741be1ba955ccbe5cd17c696" + "reference": "952f45d1c5077e658cb16a61d11603bee873f968" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/133e649fdf08aeb8741be1ba955ccbe5cd17c696", - "reference": "133e649fdf08aeb8741be1ba955ccbe5cd17c696", + "url": "https://api.github.com/repos/symfony/flex/zipball/952f45d1c5077e658cb16a61d11603bee873f968", + "reference": "952f45d1c5077e658cb16a61d11603bee873f968", "shasum": "" }, "require": { @@ -4399,14 +4665,14 @@ }, "require-dev": { "composer/composer": "^1.0.2", - "symfony/dotenv": "^3.4|^4.0", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8", - "symfony/process": "^2.7|^3.0|^4.0" + "symfony/dotenv": "^3.4|^4.0|^5.0", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0", + "symfony/process": "^2.7|^3.0|^4.0|^5.0" }, "type": "composer-plugin", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" }, "class": "Symfony\\Flex\\Flex" }, @@ -4426,31 +4692,31 @@ } ], "description": "Composer plugin for Symfony", - "time": "2019-09-19T14:55:57+00:00" + "time": "2019-12-13T18:05:11+00:00" }, { "name": "symfony/form", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "eba11fd575e791d72030cb59215a9948791f1e74" + "reference": "7ed4441a347fe33299908a9aa24ff8a556848a16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/eba11fd575e791d72030cb59215a9948791f1e74", - "reference": "eba11fd575e791d72030cb59215a9948791f1e74", + "url": "https://api.github.com/repos/symfony/form/zipball/7ed4441a347fe33299908a9aa24ff8a556848a16", + "reference": "7ed4441a347fe33299908a9aa24ff8a556848a16", "shasum": "" }, "require": { "php": "^7.1.3", "symfony/event-dispatcher": "^4.3", - "symfony/intl": "^4.3", - "symfony/options-resolver": "~4.3", + "symfony/intl": "^4.4|^5.0", + "symfony/options-resolver": "~4.3|^5.0", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/property-access": "~3.4|~4.0", - "symfony/service-contracts": "~1.1" + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/service-contracts": "^1.1|^2" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", @@ -4458,22 +4724,22 @@ "symfony/dependency-injection": "<3.4", "symfony/doctrine-bridge": "<3.4", "symfony/framework-bundle": "<3.4", - "symfony/http-kernel": "<4.3", + "symfony/http-kernel": "<4.4", "symfony/intl": "<4.3", "symfony/translation": "<4.2", "symfony/twig-bridge": "<3.4.5|<4.0.5,>=4.0" }, "require-dev": { "doctrine/collections": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/console": "^4.3", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "~4.3", - "symfony/security-csrf": "~3.4|~4.0", - "symfony/translation": "~4.2", - "symfony/validator": "^3.4.31|^4.3.4", - "symfony/var-dumper": "^4.3" + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^4.3|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/security-csrf": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2|^5.0", + "symfony/validator": "^3.4.31|^4.3.4|^5.0", + "symfony/var-dumper": "^4.3|^5.0" }, "suggest": { "symfony/security-csrf": "For protecting forms against CSRF attacks.", @@ -4483,7 +4749,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4510,7 +4776,7 @@ ], "description": "Symfony Form Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-12-16T11:07:37+00:00" }, { "name": "symfony/framework-bundle", @@ -4637,38 +4903,44 @@ }, { "name": "symfony/http-client", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "9a4fa769269ed730196a5c52c742b30600cf1e87" + "reference": "9ebfc77b5018a05226b38642def82746f3e2ce0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/9a4fa769269ed730196a5c52c742b30600cf1e87", - "reference": "9a4fa769269ed730196a5c52c742b30600cf1e87", + "url": "https://api.github.com/repos/symfony/http-client/zipball/9ebfc77b5018a05226b38642def82746f3e2ce0f", + "reference": "9ebfc77b5018a05226b38642def82746f3e2ce0f", "shasum": "" }, "require": { "php": "^7.1.3", "psr/log": "^1.0", - "symfony/http-client-contracts": "^1.1.6", - "symfony/polyfill-php73": "^1.11" + "symfony/http-client-contracts": "^1.1.8|^2", + "symfony/polyfill-php73": "^1.11", + "symfony/service-contracts": "^1.0|^2" }, "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", "psr/http-client-implementation": "1.0", "symfony/http-client-implementation": "1.1" }, "require-dev": { + "guzzlehttp/promises": "^1.3.1", "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", - "symfony/http-kernel": "^4.3", - "symfony/process": "^4.2" + "symfony/dependency-injection": "^4.3|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/process": "^4.2|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4695,24 +4967,24 @@ ], "description": "Symfony HttpClient component", "homepage": "https://symfony.com", - "time": "2019-08-20T14:27:59+00:00" + "time": "2019-12-19T15:57:49+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v1.1.6", + "version": "v2.0.1", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "6005fe61a33724405d56eb5b055d5d370192a1bd" + "reference": "378868b61b85c5cac6822d4f84e26999c9f2e881" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/6005fe61a33724405d56eb5b055d5d370192a1bd", - "reference": "6005fe61a33724405d56eb5b055d5d370192a1bd", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/378868b61b85c5cac6822d4f84e26999c9f2e881", + "reference": "378868b61b85c5cac6822d4f84e26999c9f2e881", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.2.5" }, "suggest": { "symfony/http-client-implementation": "" @@ -4720,7 +4992,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -4752,20 +5024,20 @@ "interoperability", "standards" ], - "time": "2019-08-08T10:05:21+00:00" + "time": "2019-11-26T23:25:11+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5" + "reference": "fcae1cff5b57b2a9c3aabefeb1527678705ddb62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8bccc59e61b41963d14c3dbdb23181e5c932a1d5", - "reference": "8bccc59e61b41963d14c3dbdb23181e5c932a1d5", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/fcae1cff5b57b2a9c3aabefeb1527678705ddb62", + "reference": "fcae1cff5b57b2a9c3aabefeb1527678705ddb62", "shasum": "" }, "require": { @@ -4807,37 +5079,37 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-11-28T13:33:56+00:00" + "time": "2019-12-19T15:57:49+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.3.9", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "3feb99b01560f94173d8fbc5a203ea497d01d499" + "reference": "fe310d2e95cd4c356836c8ecb0895a46d97fede2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3feb99b01560f94173d8fbc5a203ea497d01d499", - "reference": "3feb99b01560f94173d8fbc5a203ea497d01d499", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/fe310d2e95cd4c356836c8ecb0895a46d97fede2", + "reference": "fe310d2e95cd4c356836c8ecb0895a46d97fede2", "shasum": "" }, "require": { "php": "^7.1.3", "psr/log": "~1.0", - "symfony/debug": "~3.4|~4.0", - "symfony/event-dispatcher": "^4.3", - "symfony/http-foundation": "^4.1.1", - "symfony/polyfill-ctype": "~1.8", + "symfony/error-handler": "^4.4", + "symfony/event-dispatcher": "^4.4", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9" }, "conflict": { "symfony/browser-kit": "<4.3", "symfony/config": "<3.4", + "symfony/console": ">=5", "symfony/dependency-injection": "<4.3", "symfony/translation": "<4.2", - "symfony/var-dumper": "<4.1.1", "twig/twig": "<1.34|<2.4,>=2" }, "provide": { @@ -4845,34 +5117,32 @@ }, "require-dev": { "psr/cache": "~1.0", - "symfony/browser-kit": "^4.3", - "symfony/config": "~3.4|~4.0", - "symfony/console": "~3.4|~4.0", - "symfony/css-selector": "~3.4|~4.0", - "symfony/dependency-injection": "^4.3", - "symfony/dom-crawler": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0", - "symfony/routing": "~3.4|~4.0", - "symfony/stopwatch": "~3.4|~4.0", - "symfony/templating": "~3.4|~4.0", - "symfony/translation": "~4.2", - "symfony/translation-contracts": "^1.1", - "symfony/var-dumper": "^4.1.1", - "twig/twig": "^1.34|^2.4" + "symfony/browser-kit": "^4.3|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0", + "symfony/css-selector": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^4.3|^5.0", + "symfony/dom-crawler": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/routing": "^3.4|^4.0|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/templating": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "twig/twig": "^1.34|^2.4|^3.0" }, "suggest": { "symfony/browser-kit": "", "symfony/config": "", "symfony/console": "", - "symfony/dependency-injection": "", - "symfony/var-dumper": "" + "symfony/dependency-injection": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -4899,11 +5169,11 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2019-12-01T14:00:23+00:00" + "time": "2019-12-19T16:23:40+00:00" }, { "name": "symfony/inflector", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/inflector.git", @@ -4961,16 +5231,16 @@ }, { "name": "symfony/intl", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "8db5505703c5bdb23d524fd994dad2f781966538" + "reference": "727fed5372915b5ea5e8177070f5e7e547063f24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/8db5505703c5bdb23d524fd994dad2f781966538", - "reference": "8db5505703c5bdb23d524fd994dad2f781966538", + "url": "https://api.github.com/repos/symfony/intl/zipball/727fed5372915b5ea5e8177070f5e7e547063f24", + "reference": "727fed5372915b5ea5e8177070f5e7e547063f24", "shasum": "" }, "require": { @@ -4978,7 +5248,7 @@ "symfony/polyfill-intl-icu": "~1.0" }, "require-dev": { - "symfony/filesystem": "~3.4|~4.0" + "symfony/filesystem": "^3.4|^4.0|^5.0" }, "suggest": { "ext-intl": "to use the component with locales other than \"en\"" @@ -4986,7 +5256,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5032,44 +5302,44 @@ "l10n", "localization" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-26T23:16:41+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.13.0", + "version": "v1.14.3", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "c4388410e2fb6321e77c5dd6e3cb2dba821f9fe6" + "reference": "c864e7f9b8d1e1f5f60acc3beda11299f637aded" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c4388410e2fb6321e77c5dd6e3cb2dba821f9fe6", - "reference": "c4388410e2fb6321e77c5dd6e3cb2dba821f9fe6", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c864e7f9b8d1e1f5f60acc3beda11299f637aded", + "reference": "c864e7f9b8d1e1f5f60acc3beda11299f637aded", "shasum": "" }, "require": { "doctrine/inflector": "^1.2", "nikic/php-parser": "^4.0", "php": "^7.0.8", - "symfony/config": "^3.4|^4.0", - "symfony/console": "^3.4|^4.0", - "symfony/dependency-injection": "^3.4|^4.0", - "symfony/filesystem": "^3.4|^4.0", - "symfony/finder": "^3.4|^4.0", - "symfony/framework-bundle": "^3.4|^4.0", - "symfony/http-kernel": "^3.4|^4.0" + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/filesystem": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/framework-bundle": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^3.4|^4.0|^5.0" }, "require-dev": { - "doctrine/doctrine-bundle": "^1.8", + "doctrine/doctrine-bundle": "^1.8|^2.0", "doctrine/orm": "^2.3", "friendsofphp/php-cs-fixer": "^2.8", "friendsoftwig/twigcs": "^3.1.2", - "symfony/http-client": "^4.3", - "symfony/phpunit-bridge": "^3.4.19|^4.0", - "symfony/process": "^3.4|^4.0", - "symfony/security-core": "^3.4|^4.0", - "symfony/yaml": "^3.4|^4.0" + "symfony/http-client": "^4.3|^5.0", + "symfony/phpunit-bridge": "^4.3|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/security-core": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "type": "symfony-bundle", "extra": { @@ -5100,33 +5370,37 @@ "scaffold", "scaffolding" ], - "time": "2019-08-18T17:34:03+00:00" + "time": "2019-11-07T00:56:03+00:00" }, { "name": "symfony/mercure", - "version": "v0.2.0", + "version": "v0.3.0", "source": { "type": "git", "url": "https://github.com/symfony/mercure.git", - "reference": "c74981184bf13f225c9a669cf28d06d0f4197593" + "reference": "999c125d3a8f96a2b6e9be3da40ff4c25844d1da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mercure/zipball/c74981184bf13f225c9a669cf28d06d0f4197593", - "reference": "c74981184bf13f225c9a669cf28d06d0f4197593", + "url": "https://api.github.com/repos/symfony/mercure/zipball/999c125d3a8f96a2b6e9be3da40ff4c25844d1da", + "reference": "999c125d3a8f96a2b6e9be3da40ff4c25844d1da", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/http-client": "^4.3" + "symfony/http-client": "^4.3.5|^5.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.2.4" + "symfony/phpunit-bridge": "^4.2.4|^5.0", + "symfony/stopwatch": "^4.3|^5.0" + }, + "suggest": { + "symfony/stopwatch": "Integration with the profiler performances" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "0.3.x-dev" }, "thanks": { "name": "dunglas/mercure", @@ -5160,31 +5434,33 @@ "sse", "updates" ], - "time": "2019-06-20T20:34:51+00:00" + "time": "2019-11-08T19:13:31+00:00" }, { "name": "symfony/mercure-bundle", - "version": "v0.1.2", + "version": "0.2.3", "source": { "type": "git", "url": "https://github.com/symfony/mercure-bundle.git", - "reference": "f8b538b94164fa46b80562ed6b0ba121cd3836dd" + "reference": "9c5fe6e761816449d84d5f0429e74415cb0590f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/f8b538b94164fa46b80562ed6b0ba121cd3836dd", - "reference": "f8b538b94164fa46b80562ed6b0ba121cd3836dd", + "url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/9c5fe6e761816449d84d5f0429e74415cb0590f2", + "reference": "9c5fe6e761816449d84d5f0429e74415cb0590f2", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/config": "^3.4|^4.0", - "symfony/dependency-injection": "^3.4|^4.0", - "symfony/http-kernel": "^3.4|^4.0", - "symfony/mercure": "^0.2" + "symfony/config": "^4.3.7|^5.0", + "symfony/dependency-injection": "^4.3.7|^5.0", + "symfony/http-kernel": "^4.3.7|^5.0", + "symfony/mercure": "^0.3" }, "require-dev": { - "symfony/phpunit-bridge": "^4.2.4" + "symfony/phpunit-bridge": "^4.3.7|^5.0", + "symfony/stopwatch": "^4.3.7|^5.0", + "symfony/var-dumper": "^4.3.7|^5.0" }, "suggest": { "symfony/messenger": "To use the Messenger integration" @@ -5192,7 +5468,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "0.2.x-dev" } }, "autoload": { @@ -5222,11 +5498,11 @@ "sse", "updates" ], - "time": "2019-06-24T19:45:57+00:00" + "time": "2019-11-24T10:29:29+00:00" }, { "name": "symfony/mime", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", @@ -5288,16 +5564,16 @@ }, { "name": "symfony/options-resolver", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "81c2e120522a42f623233968244baebd6b36cb6a" + "reference": "2be23e63f33de16b49294ea6581f462932a77e2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/81c2e120522a42f623233968244baebd6b36cb6a", - "reference": "81c2e120522a42f623233968244baebd6b36cb6a", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/2be23e63f33de16b49294ea6581f462932a77e2f", + "reference": "2be23e63f33de16b49294ea6581f462932a77e2f", "shasum": "" }, "require": { @@ -5306,7 +5582,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5338,20 +5614,20 @@ "configuration", "options" ], - "time": "2019-08-08T09:29:19+00:00" + "time": "2019-10-28T21:57:16+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.12.0", + "version": "v1.13.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "66810b9d6eb4af54d543867909d65ab9af654d7e" + "reference": "b3dffd68afa61ca70f2327f2dd9bbeb6aa53d70b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/66810b9d6eb4af54d543867909d65ab9af654d7e", - "reference": "66810b9d6eb4af54d543867909d65ab9af654d7e", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/b3dffd68afa61ca70f2327f2dd9bbeb6aa53d70b", + "reference": "b3dffd68afa61ca70f2327f2dd9bbeb6aa53d70b", "shasum": "" }, "require": { @@ -5364,7 +5640,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.13-dev" } }, "autoload": { @@ -5396,7 +5672,7 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2019-11-27T13:56:44+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -5634,16 +5910,16 @@ }, { "name": "symfony/process", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a" + "reference": "b84501ad50adb72a94fb460a5b5c91f693e99c9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e89969c00d762349f078db1128506f7f3dcc0d4a", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a", + "url": "https://api.github.com/repos/symfony/process/zipball/b84501ad50adb72a94fb460a5b5c91f693e99c9b", + "reference": "b84501ad50adb72a94fb460a5b5c91f693e99c9b", "shasum": "" }, "require": { @@ -5652,7 +5928,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5679,20 +5955,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-06T10:06:46+00:00" }, { "name": "symfony/property-access", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc" + "reference": "055fe3134f8f301ff44af314d83463b858ea6413" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc", - "reference": "bafdc8c3a9d2671af4a81baec0fcc4687c0c17bc", + "url": "https://api.github.com/repos/symfony/property-access/zipball/055fe3134f8f301ff44af314d83463b858ea6413", + "reference": "055fe3134f8f301ff44af314d83463b858ea6413", "shasum": "" }, "require": { @@ -5746,25 +6022,25 @@ "property path", "reflection" ], - "time": "2019-12-01T10:50:45+00:00" + "time": "2019-12-10T10:33:21+00:00" }, { "name": "symfony/property-info", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "29546235b37f7bd279c763314cd4c962aedd1e6d" + "reference": "8afd280f159697177e48eefa89efd4db60a57665" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/29546235b37f7bd279c763314cd4c962aedd1e6d", - "reference": "29546235b37f7bd279c763314cd4c962aedd1e6d", + "url": "https://api.github.com/repos/symfony/property-info/zipball/8afd280f159697177e48eefa89efd4db60a57665", + "reference": "8afd280f159697177e48eefa89efd4db60a57665", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/inflector": "~3.4|~4.0" + "symfony/inflector": "^3.4|^4.0|^5.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2", @@ -5774,9 +6050,9 @@ "require-dev": { "doctrine/annotations": "~1.7", "phpdocumentor/reflection-docblock": "^3.0|^4.0", - "symfony/cache": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/serializer": "~3.4|~4.0" + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/serializer": "^3.4|^4.0|^5.0" }, "suggest": { "phpdocumentor/reflection-docblock": "To use the PHPDoc", @@ -5787,7 +6063,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5822,20 +6098,20 @@ "type", "validator" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-11-05T16:11:08+00:00" }, { "name": "symfony/routing", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "ff1049f6232dc5b6023b1ff1c6de56f82bcd264f" + "reference": "628bcafae1b2043969378dcfbf9c196539a38722" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/ff1049f6232dc5b6023b1ff1c6de56f82bcd264f", - "reference": "ff1049f6232dc5b6023b1ff1c6de56f82bcd264f", + "url": "https://api.github.com/repos/symfony/routing/zipball/628bcafae1b2043969378dcfbf9c196539a38722", + "reference": "628bcafae1b2043969378dcfbf9c196539a38722", "shasum": "" }, "require": { @@ -5849,11 +6125,11 @@ "require-dev": { "doctrine/annotations": "~1.2", "psr/log": "~1.0", - "symfony/config": "~4.2", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/annotations": "For using the annotation loader", @@ -5865,7 +6141,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -5898,7 +6174,7 @@ "uri", "url" ], - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-12T12:53:52+00:00" }, { "name": "symfony/security-bundle", @@ -5986,16 +6262,16 @@ }, { "name": "symfony/security-core", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "312c91f90786fd7add89e8542cfc98543f0e60db" + "reference": "52709ee2aafd13d777253d510d96fbf2ccc5a578" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/312c91f90786fd7add89e8542cfc98543f0e60db", - "reference": "312c91f90786fd7add89e8542cfc98543f0e60db", + "url": "https://api.github.com/repos/symfony/security-core/zipball/52709ee2aafd13d777253d510d96fbf2ccc5a578", + "reference": "52709ee2aafd13d777253d510d96fbf2ccc5a578", "shasum": "" }, "require": { @@ -6055,31 +6331,31 @@ ], "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", - "time": "2019-11-20T10:44:55+00:00" + "time": "2019-12-16T11:07:37+00:00" }, { "name": "symfony/security-csrf", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "d218ba086ef4a68081f3dd5ec11611f5d64d58f3" + "reference": "aeed1a2315019b5a090f5ad34c01f1935ea9b757" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/d218ba086ef4a68081f3dd5ec11611f5d64d58f3", - "reference": "d218ba086ef4a68081f3dd5ec11611f5d64d58f3", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/aeed1a2315019b5a090f5ad34c01f1935ea9b757", + "reference": "aeed1a2315019b5a090f5ad34c01f1935ea9b757", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/security-core": "~3.4|~4.0" + "symfony/security-core": "^3.4|^4.0|^5.0" }, "conflict": { "symfony/http-foundation": "<3.4" }, "require-dev": { - "symfony/http-foundation": "~3.4|~4.0" + "symfony/http-foundation": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/http-foundation": "For using the class SessionTokenStorage." @@ -6087,7 +6363,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6114,26 +6390,26 @@ ], "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", - "time": "2019-08-13T06:39:03+00:00" + "time": "2019-10-12T00:35:04+00:00" }, { "name": "symfony/security-guard", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-guard.git", - "reference": "cf06aa4f8ea38a769476c4f5989f1dc400a308a1" + "reference": "203a81f9fcfc3bbaba7f1103c261a30d2648611b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-guard/zipball/cf06aa4f8ea38a769476c4f5989f1dc400a308a1", - "reference": "cf06aa4f8ea38a769476c4f5989f1dc400a308a1", + "url": "https://api.github.com/repos/symfony/security-guard/zipball/203a81f9fcfc3bbaba7f1103c261a30d2648611b", + "reference": "203a81f9fcfc3bbaba7f1103c261a30d2648611b", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/security-core": "~3.4.22|^4.2.3", - "symfony/security-http": "^4.3" + "symfony/security-core": "^3.4.22|^4.2.3|^5.0", + "symfony/security-http": "^4.4.1" }, "require-dev": { "psr/log": "~1.0" @@ -6141,7 +6417,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6168,36 +6444,37 @@ ], "description": "Symfony Security Component - Guard", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-07T16:27:44+00:00" }, { "name": "symfony/security-http", - "version": "v4.3.9", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "75e96df3a1b9b38c67e2fa208894f72dae5e1147" + "reference": "8ab510f214fd9c37769378b5036da58d444fe142" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/75e96df3a1b9b38c67e2fa208894f72dae5e1147", - "reference": "75e96df3a1b9b38c67e2fa208894f72dae5e1147", + "url": "https://api.github.com/repos/symfony/security-http/zipball/8ab510f214fd9c37769378b5036da58d444fe142", + "reference": "8ab510f214fd9c37769378b5036da58d444fe142", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "^4.3", - "symfony/property-access": "~3.4|~4.0", - "symfony/security-core": "^4.3" + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/security-core": "^4.4" }, "conflict": { + "symfony/event-dispatcher": ">=5", "symfony/security-csrf": "<3.4.11|~4.0,<4.0.11" }, "require-dev": { "psr/log": "~1.0", - "symfony/routing": "~3.4|~4.0", - "symfony/security-csrf": "^3.4.11|^4.0.11" + "symfony/routing": "^3.4|^4.0|^5.0", + "symfony/security-csrf": "^3.4.11|^4.0.11|^5.0" }, "suggest": { "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs", @@ -6206,7 +6483,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6233,20 +6510,20 @@ ], "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", - "time": "2019-11-30T13:16:45+00:00" + "time": "2019-12-13T12:11:48+00:00" }, { "name": "symfony/serializer", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "702900654e0ceed9ca7a9eccffb1d6ec69d7c8b6" + "reference": "e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/702900654e0ceed9ca7a9eccffb1d6ec69d7c8b6", - "reference": "702900654e0ceed9ca7a9eccffb1d6ec69d7c8b6", + "url": "https://api.github.com/repos/symfony/serializer/zipball/e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e", + "reference": "e5bc3f6dee44dc06e7e640cce4baa741b73ecb6e", "shasum": "" }, "require": { @@ -6263,15 +6540,16 @@ "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "phpdocumentor/reflection-docblock": "^3.0|^4.0", - "symfony/cache": "~3.4|~4.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/http-foundation": "~3.4|~4.0", - "symfony/property-access": "~3.4|~4.0", - "symfony/property-info": "^3.4.13|~4.0", - "symfony/validator": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "phpdocumentor/reflection-docblock": "^3.2|^4.0", + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/property-info": "^3.4.13|~4.0|^5.0", + "symfony/validator": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", @@ -6286,7 +6564,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6313,7 +6591,7 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "time": "2019-12-16T11:07:37+00:00" }, { "name": "symfony/service-contracts", @@ -6375,26 +6653,26 @@ }, { "name": "symfony/stopwatch", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71" + "reference": "5745b514fc56ae1907c6b8ed74f94f90f64694e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/1e4ff456bd625be5032fac9be4294e60442e9b71", - "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5745b514fc56ae1907c6b8ed74f94f90f64694e9", + "reference": "5745b514fc56ae1907c6b8ed74f94f90f64694e9", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/service-contracts": "^1.0" + "symfony/service-contracts": "^1.0|^2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6421,24 +6699,24 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2019-08-07T11:52:19+00:00" + "time": "2019-11-05T16:11:08+00:00" }, { "name": "symfony/translation-contracts", - "version": "v1.1.6", + "version": "v2.0.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "325b17c24f3ee23cbecfa63ba809c6d89b5fa04a" + "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/325b17c24f3ee23cbecfa63ba809c6d89b5fa04a", - "reference": "325b17c24f3ee23cbecfa63ba809c6d89b5fa04a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/8cc682ac458d75557203b2f2f14b0b92e1c744ed", + "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.2.5" }, "suggest": { "symfony/translation-implementation": "" @@ -6446,7 +6724,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -6478,59 +6756,61 @@ "interoperability", "standards" ], - "time": "2019-08-02T12:15:04+00:00" + "time": "2019-11-18T17:27:11+00:00" }, { "name": "symfony/twig-bridge", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "cd6c551dc5d62b520d1a973fb4cb2c46bfc00b62" + "reference": "936cf6f5b973377345e8ac43870987ef8e747ce3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/cd6c551dc5d62b520d1a973fb4cb2c46bfc00b62", - "reference": "cd6c551dc5d62b520d1a973fb4cb2c46bfc00b62", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/936cf6f5b973377345e8ac43870987ef8e747ce3", + "reference": "936cf6f5b973377345e8ac43870987ef8e747ce3", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/translation-contracts": "^1.1", - "twig/twig": "^1.41|^2.10" + "symfony/translation-contracts": "^1.1|^2", + "twig/twig": "^1.41|^2.10|^3.0" }, "conflict": { "symfony/console": "<3.4", - "symfony/form": "<4.3.4", + "symfony/form": "<4.4", "symfony/http-foundation": "<4.3", "symfony/translation": "<4.2", "symfony/workflow": "<4.3" }, "require-dev": { "egulias/email-validator": "^2.1.10", - "fig/link-util": "^1.0", - "symfony/asset": "~3.4|~4.0", - "symfony/console": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/finder": "~3.4|~4.0", - "symfony/form": "^4.3.4", - "symfony/http-foundation": "~4.3", - "symfony/http-kernel": "~3.4|~4.0", - "symfony/mime": "~4.3", + "symfony/asset": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/form": "^4.3.5", + "symfony/http-foundation": "^4.3|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/mime": "^4.3|^5.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/routing": "~3.4|~4.0", - "symfony/security-acl": "~2.8|~3.0", - "symfony/security-core": "~3.0|~4.0", - "symfony/security-csrf": "~3.4|~4.0", - "symfony/security-http": "~3.4|~4.0", - "symfony/stopwatch": "~3.4|~4.0", - "symfony/templating": "~3.4|~4.0", - "symfony/translation": "^4.2.1", - "symfony/var-dumper": "~3.4|~4.0", - "symfony/web-link": "~3.4|~4.0", - "symfony/workflow": "~4.3", - "symfony/yaml": "~3.4|~4.0" + "symfony/routing": "^3.4|^4.0|^5.0", + "symfony/security-acl": "^2.8|^3.0", + "symfony/security-core": "^3.0|^4.0|^5.0", + "symfony/security-csrf": "^3.4|^4.0|^5.0", + "symfony/security-http": "^3.4|^4.0|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/templating": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2.1|^5.0", + "symfony/web-link": "^4.4|^5.0", + "symfony/workflow": "^4.3|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0", + "twig/cssinliner-extra": "^2.12", + "twig/inky-extra": "^2.12", + "twig/markdown-extra": "^2.12" }, "suggest": { "symfony/asset": "For using the AssetExtension", @@ -6552,7 +6832,7 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6579,7 +6859,7 @@ ], "description": "Symfony Twig Bridge", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "time": "2019-12-05T05:58:42+00:00" }, { "name": "symfony/twig-bundle", @@ -6660,56 +6940,55 @@ }, { "name": "symfony/validator", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "173b483999c2acad8e040633105733318dcc8a83" + "reference": "79eb122bed116c1fbe0769698d5b46acce1860a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/173b483999c2acad8e040633105733318dcc8a83", - "reference": "173b483999c2acad8e040633105733318dcc8a83", + "url": "https://api.github.com/repos/symfony/validator/zipball/79eb122bed116c1fbe0769698d5b46acce1860a2", + "reference": "79eb122bed116c1fbe0769698d5b46acce1860a2", "shasum": "" }, "require": { "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^1.1" + "symfony/translation-contracts": "^1.1|^2" }, "conflict": { "doctrine/lexer": "<1.0.2", "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<3.4", + "symfony/http-kernel": "<4.4", "symfony/intl": "<4.3", - "symfony/translation": "<4.2", + "symfony/translation": ">=5.0", "symfony/yaml": "<3.4" }, "require-dev": { "doctrine/annotations": "~1.7", "doctrine/cache": "~1.0", "egulias/email-validator": "^2.1.10", - "symfony/cache": "~3.4|~4.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/expression-language": "~3.4|~4.0", - "symfony/http-client": "^4.3", - "symfony/http-foundation": "~4.1", - "symfony/http-kernel": "~3.4|~4.0", - "symfony/intl": "^4.3", - "symfony/property-access": "~3.4|~4.0", - "symfony/property-info": "~3.4|~4.0", - "symfony/translation": "~4.2", - "symfony/var-dumper": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/http-client": "^4.3|^5.0", + "symfony/http-foundation": "^4.1|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/intl": "^4.3|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/property-info": "^3.4|^4.0|^5.0", + "symfony/translation": "^4.2", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "doctrine/cache": "For using the default cached annotation reader.", "egulias/email-validator": "Strict (RFC compliant) email validation", - "psr/cache-implementation": "For using the metadata cache.", + "psr/cache-implementation": "For using the mapping cache.", "symfony/config": "", "symfony/expression-language": "For using the Expression validator", "symfony/http-foundation": "", @@ -6722,7 +7001,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6749,11 +7028,87 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "time": "2019-08-26T09:28:48+00:00" + "time": "2019-12-17T08:15:02+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v4.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "be330f919bdb395d1e0c3f2bfb8948512d6bdd99" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/be330f919bdb395d1e0c3f2bfb8948512d6bdd99", + "reference": "be330f919bdb395d1e0c3f2bfb8948512d6bdd99", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/console": "<3.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "time": "2019-12-18T13:41:29+00:00" }, { "name": "symfony/var-exporter", - "version": "v4.4.1", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", @@ -6813,29 +7168,32 @@ }, { "name": "symfony/web-link", - "version": "v4.3.4", + "version": "v4.4.2", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "4bd0ce7c54d604300deee8eb1b1beda856fbba20" + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/4bd0ce7c54d604300deee8eb1b1beda856fbba20", - "reference": "4bd0ce7c54d604300deee8eb1b1beda856fbba20", + "url": "https://api.github.com/repos/symfony/web-link/zipball/bc6432b92681b2f28ced2f3bbcf051e75eea569c", + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c", "shasum": "" }, "require": { - "fig/link-util": "^1.0", "php": "^7.1.3", - "psr/link": "^1.0" + "psr/link": "^1.0", + "symfony/polyfill-php72": "^1.5" }, "conflict": { "symfony/http-kernel": "<4.3" }, + "provide": { + "psr/link-implementation": "1.0" + }, "require-dev": { - "symfony/http-foundation": "~3.4|~4.0", - "symfony/http-kernel": "^4.3" + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.3|^5.0" }, "suggest": { "symfony/http-kernel": "" @@ -6843,7 +7201,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -6882,7 +7240,7 @@ "psr13", "push" ], - "time": "2019-08-08T09:29:19+00:00" + "time": "2019-10-12T00:35:04+00:00" }, { "name": "symfony/yaml", @@ -7018,16 +7376,16 @@ }, { "name": "twig/twig", - "version": "v2.11.3", + "version": "v2.12.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "699ed2342557c88789a15402de5eb834dedd6792" + "reference": "d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/699ed2342557c88789a15402de5eb834dedd6792", - "reference": "699ed2342557c88789a15402de5eb834dedd6792", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed", + "reference": "d761fd1f1c6b867ae09a7d8119a6d95d06dc44ed", "shasum": "" }, "require": { @@ -7037,13 +7395,13 @@ }, "require-dev": { "psr/container": "^1.0", - "symfony/debug": "^2.7", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0" + "symfony/debug": "^3.4|^4.2", + "symfony/phpunit-bridge": "^4.4@dev|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.11-dev" + "dev-master": "2.12-dev" } }, "autoload": { @@ -7065,15 +7423,15 @@ "homepage": "http://fabien.potencier.org", "role": "Lead Developer" }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, { "name": "Twig Team", "homepage": "https://twig.symfony.com/contributors", "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" } ], "description": "Twig, the flexible, fast, and secure template language for PHP", @@ -7081,35 +7439,33 @@ "keywords": [ "templating" ], - "time": "2019-06-18T15:37:11+00:00" + "time": "2019-11-11T16:52:09+00:00" }, { "name": "webmozart/assert", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", + "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0", "symfony/polyfill-ctype": "^1.8" }, + "conflict": { + "vimeo/psalm": "<3.6.0" + }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -7131,7 +7487,7 @@ "check", "validate" ], - "time": "2019-08-24T08:43:50+00:00" + "time": "2019-11-24T13:36:37+00:00" }, { "name": "webonyx/graphql-php", @@ -7267,82 +7623,6 @@ "description": "A pack for the Symfony web profiler", "time": "2018-12-10T12:11:44+00:00" }, - { - "name": "symfony/var-dumper", - "version": "v4.3.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "641043e0f3e615990a0f29479f9c117e8a6698c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/641043e0f3e615990a0f29479f9c117e8a6698c6", - "reference": "641043e0f3e615990a0f29479f9c117e8a6698c6", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5" - }, - "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/console": "<3.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0", - "twig/twig": "~1.34|~2.4" - }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.3-dev" - } - }, - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony mechanism for exploring and dumping PHP variables", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "time": "2019-08-26T08:26:39+00:00" - }, { "name": "symfony/web-profiler-bundle", "version": "v4.3.4", diff --git a/api/config/bundles.php b/api/config/bundles.php index 426c3ab7..0b350522 100644 --- a/api/config/bundles.php +++ b/api/config/bundles.php @@ -2,10 +2,10 @@ return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true], Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true], @@ -13,7 +13,8 @@ Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Conduction\CommonGroundBundle\CommonGroundBundle::class => ['all' => true], Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], - Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], - Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], + Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], Tbbc\MoneyBundle\TbbcMoneyBundle::class => ['all' => true], + Knp\Bundle\MarkdownBundle\KnpMarkdownBundle::class => ['all' => true], ]; diff --git a/api/config/packages/api_platform.yaml b/api/config/packages/api_platform.yaml index de2b19c8..58417518 100644 --- a/api/config/packages/api_platform.yaml +++ b/api/config/packages/api_platform.yaml @@ -4,18 +4,23 @@ parameters: # environment variables are not available yet. # You should not need to change this value. env(VARNISH_URL): '' - env(APP_VERSION): '' + env(APP_VERSION): ' + env(APP_NAME): ''' env(APP_TITLE): '' env(APP_DESCRIPTION): '' env(APP_REPRO): '' env(APP_DEMO): '' env(APP_ENV): '' + env(AUTH_ENABLED): '' + env(AUDITTRAIL_ENABLED): '' + env(NOTIFICATION_ENABLED): '' + env(HEALTH_ENABLED): '' + env(ARCHIVE_ENABLED): '' env(CONTAINER_REGISTRY_BASE): '' - env(CONTAINER_PROJECT_TITLE): '' env(CONTAINER_PROJECT_NAME): '' - env(CONTAINER_PROJECT_VERSION): '' + env(CONTAINER_REPRO): '' -api_platform: +api_platform: mapping: paths: ['%kernel.project_dir%/src/Entity'] @@ -23,19 +28,15 @@ api_platform: title: '%env(APP_TITLE)%' description: | API Details - - Component: %env(CONTAINER_PROJECT_TITLE)% - - Reference: %env(CONTAINER_PROJECT_NAME)% + - Component: %env(APP_TITLE)% + - Reference: %env(APP_NAME)% - Enviroment: %env(APP_ENV)% - - Version: %env(CONTAINER_PROJECT_VERSION)% - - Repository: [%env(APP_REPRO)%](%env(APP_REPRO)%) / [zip](%env(APP_REPRO)%/archive/master.zip) - - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) - - %env(APP_DESCRIPTION)% - - Voor het gebruik van deze applicatie is een JWT Token nodig, deze hangt altijd vast aan een applicatie, ofwel user. Geldige JWT Tokens worden aangemaakt bij het registreren van een applicatie en kennen een beperkte houdbaarheid. - JWT Tokens kunnen zowel worden verlengd, als opnieuw worden aangevraagd, dit aan de hand van de applicatie id en sleutel. - Let er bij het meegeven van JWT tokens op dat deze moet worden voorafgegaan door een Bearer en een spatie, onder de header Authorization. De volledig naam wordt daarmee: 'Authorization: Bearer [TOKEN]'. + - Version: %env(APP_VERSION)% + - Repository: [online](%env(APP_REPRO)%) / [zip](%env(APP_REPRO)%/archive/master.zip) + - Docker Image: [online](%env(CONTAINER_REPRO)%) + - Datamodel: [postman](/schema/%env(APP_NAME)%.postman_collection.json) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) + %env(APP_DESCRIPTION)% version: '%env(APP_VERSION)%' @@ -45,7 +46,7 @@ api_platform: enable_re_doc: true # In the NL api strategie we use snake case for naming - name_converter: 'Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter' + # name_converter: 'Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter' # Lets confirm to JSON-HA: first, as per common ground. But allow other serializers formats: diff --git a/api/config/packages/doctrine.yaml b/api/config/packages/doctrine.yaml index b935c8e3..dae8287b 100644 --- a/api/config/packages/doctrine.yaml +++ b/api/config/packages/doctrine.yaml @@ -1,3 +1,7 @@ +parameters: + env(DATABASE_URL): 'postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1' + # Organisation stuff + doctrine: dbal: # configure these for your database server diff --git a/api/config/packages/sensio_framework_extra.yaml b/api/config/packages/sensio_framework_extra.yaml new file mode 100644 index 00000000..1821ccc0 --- /dev/null +++ b/api/config/packages/sensio_framework_extra.yaml @@ -0,0 +1,3 @@ +sensio_framework_extra: + router: + annotations: false diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml index d58f0a2d..5a403c45 100644 --- a/api/config/packages/twig.yaml +++ b/api/config/packages/twig.yaml @@ -1,3 +1,36 @@ +parameters: + # Organisation stuff + env(GOOGLE_TAG_MANAGER_ID): '' + env(HUBSPOT_EMBED_CODE): '' + env(CONTAINER_REGISTRY_BASE): '' + env(CONTAINER_PROJECT_NAME): '' + env(ORGANIZATION_NAME): '' + env(ORGANIZATION_EMAIL_ADDRESS): '' + env(ORGANIZATION_COUNTRY_NAME): '' + env(ORGANIZATION_STATE): '' + env(ORGANIZATION_LOCALITY): '' + env(ORGANIZATION_UNIT_NAME): '' + env(APP_NAME): '' + env(APP_TITLE): '' + env(APP_LOGO): '' + env(APP_HOME): '' + env(APP_VERSION): '' + env(APP_ENV): '' + env(APP_DEBUG): '' + env(APP_SUBDOMAIN): '' + env(APP_DOMAINS): '[]' + env(APP_DEMO): '' + env(APP_REPRO): '' + env(APP_DESCRIPTION): '' + env(AUTH_ENABLED): '' + env(AUDITTRAIL_ENABLED): '' + env(NOTIFICATION_ENABLED): '' + env(HEALTH_ENABLED): '' + env(TRUSTED_HOSTS): '' + env(TRUSTED_PROXIES): '' + env(NLX_OUTWAY): '' + env(NLX_INWAY): '' + twig: default_path: '%kernel.project_dir%/templates' debug: '%kernel.debug%' @@ -5,15 +38,38 @@ twig: globals: google_tag_manager_id: '%env(GOOGLE_TAG_MANAGER_ID)%' hubspot_embed_code: '%env(HUBSPOT_EMBED_CODE)%' - container_registry_base: '%env(CONTAINER_REGISTRY_BASE)%' - container_project_title: '%env(CONTAINER_PROJECT_TITLE)%' + + container_registry_base: '%env(CONTAINER_REGISTRY_BASE)%' container_project_name: '%env(CONTAINER_PROJECT_NAME)%' - container_project_version: '%env(CONTAINER_PROJECT_VERSION)%' + + organization_name: '%env(ORGANIZATION_NAME)%' + organization_email: '%env(ORGANIZATION_EMAIL_ADDRESS)%' + organization_country: '%env(ORGANIZATION_COUNTRY_NAME)%' + organization_state: '%env(ORGANIZATION_STATE)%' + organization_locality: '%env(ORGANIZATION_LOCALITY)%' + organization_unit: '%env(ORGANIZATION_UNIT_NAME)%' + + app_name: '%env(APP_NAME)%' + app_title: '%env(APP_TITLE)%' + app_logo: '%env(APP_LOGO)%' + app_home: '%env(APP_HOME)%' + app_version: '%env(APP_VERSION)%' app_env: '%env(APP_ENV)%' app_debug: '%env(APP_DEBUG)%' + app_subdomain: '%env(APP_SUBDOMAIN)%' + app_domains: '%env(json:APP_DOMAINS)%' app_demo: '%env(APP_DEMO)%' app_repro: '%env(APP_REPRO)%' app_description: '%env(APP_DESCRIPTION)%' + + app_auth: '%env(AUTH_ENABLED)%' + app_audittrail: '%env(AUDITTRAIL_ENABLED)%' + app_notification: '%env(NOTIFICATION_ENABLED)%' + app_health: '%env(HEALTH_ENABLED)%' + + trusted_hosts: '%env(TRUSTED_HOSTS)%' + trusted_proxies: '%env(TRUSTED_PROXIES)%' + nlx_outway: '%env(NLX_OUTWAY)%' nlx_inway: '%env(NLX_INWAY)%' form_themes: diff --git a/api/docker/php/docker-entrypoint.sh b/api/docker/php/docker-entrypoint.sh index 3c5a644b..59e902c4 100755 --- a/api/docker/php/docker-entrypoint.sh +++ b/api/docker/php/docker-entrypoint.sh @@ -31,9 +31,10 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then #fi #fi - if [ "$APP_ENV" != 'prod' ]; then + #wierd bug fix... + #if [ "$APP_ENV" != 'prod' ]; then composer install --prefer-dist --no-progress --no-suggest --no-interaction - fi + #fi # Lets setup an nlx certificate if needed #if [ "$APP_ENV" != 'prod' ]; then @@ -62,13 +63,17 @@ if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then echo "Loading fixtures" bin/console doctrine:fixtures:load --no-interaction + # Lets update the docs to show the latest chages echo "Creating OAS documentation" - # Let update the docs to show the latest chages bin/console api:openapi:export --output=/srv/api/public/schema/openapi.yaml --yaml --spec-version=3 + # this should only be done in an build echo "Updating Helm charts" - # Let update the docs to show the latest chages - bin/console app:helm:update --location=/srv/api/helm --spec-version=3 + bin/console app:helm:update --location=/srv/api/helm --spec-version=3 + + # this should only be done in an build + echo "Updating publiccode charts" + bin/console app:publiccode:update --location=/srv/api/public/schema/ --spec-version=0.2 fi fi diff --git a/api/docker/varnish/conf/agent_secret b/api/docker/varnish/conf/agent_secret new file mode 100644 index 00000000..8a5c9a66 --- /dev/null +++ b/api/docker/varnish/conf/agent_secret @@ -0,0 +1 @@ +admin:admin diff --git a/api/docker/varnish/conf/default.vcl b/api/docker/varnish/conf/default.vcl index ee4b45c3..ff8d2496 100644 --- a/api/docker/varnish/conf/default.vcl +++ b/api/docker/varnish/conf/default.vcl @@ -1,10 +1,10 @@ vcl 4.0; -import std; +#import std; -backend default { - .host = "php"; - .port = "80"; +#backend default { + # .host = "php"; + # .port = "80"; # Health check #.probe = { # .url = "/"; @@ -13,17 +13,17 @@ backend default { # .window = 5; # .threshold = 3; #} -} +#} # Hosts allowed to send BAN requests -acl invalidators { - "localhost"; - "php"; +#acl invalidators { +# "localhost"; +# "php"; # local Kubernetes network - "10.0.0.0"/8; - "172.16.0.0"/12; - "192.168.0.0"/16; -} +# "10.0.0.0"/8; +# "172.16.0.0"/12; +# "192.168.0.0"/16; +#} sub vcl_recv { if (req.restarts > 0) { @@ -35,9 +35,9 @@ sub vcl_recv { # To allow API Platform to ban by cache tags if (req.method == "BAN") { - if (client.ip !~ invalidators) { - return (synth(405, "Not allowed")); - } + #if (client.ip !~ invalidators) { + # return (synth(405, "Not allowed")); + #} if (req.http.ApiPlatform-Ban-Regex) { ban("obj.http.Cache-Tags ~ " + req.http.ApiPlatform-Ban-Regex); diff --git a/api/docker/varnish/conf/varnish.vcl b/api/docker/varnish/conf/varnish.vcl new file mode 100644 index 00000000..cfb1c06a --- /dev/null +++ b/api/docker/varnish/conf/varnish.vcl @@ -0,0 +1,83 @@ +vcl 4.0; + +import std; + + +# Hosts allowed to send BAN requests +acl invalidators { + "localhost"; + "php"; + # local Kubernetes network + "10.0.0.0"/8; + "172.16.0.0"/12; + "192.168.0.0"/16; +} + +sub vcl_recv { + if (req.restarts > 0) { + set req.hash_always_miss = true; + } + + # Remove the "Forwarded" HTTP header if exists (security) + unset req.http.forwarded; + + # To allow API Platform to ban by cache tags + if (req.method == "BAN") { + if (client.ip !~ invalidators) { + return (synth(405, "Not allowed")); + } + + if (req.http.ApiPlatform-Ban-Regex) { + ban("obj.http.Cache-Tags ~ " + req.http.ApiPlatform-Ban-Regex); + + return (synth(200, "Ban added")); + } + + return (synth(400, "ApiPlatform-Ban-Regex HTTP header must be set.")); + } + + # For health checks + if (req.method == "GET" && req.url == "/healthz") { + return (synth(200, "OK")); + } +} + +sub vcl_hit { + if (obj.ttl >= 0s) { + # A pure unadulterated hit, deliver it + return (deliver); + } + + if (std.healthy(req.backend_hint)) { + # The backend is healthy + # Fetch the object from the backend + return (restart); + } + + # No fresh object and the backend is not healthy + if (obj.ttl + obj.grace > 0s) { + # Deliver graced object + # Automatically triggers a background fetch + return (deliver); + } + + # No valid object to deliver + # No healthy backend to handle request + # Return error + return (synth(503, "API is down")); +} + +sub vcl_deliver { + # Don't send cache tags related headers to the client + unset resp.http.url; + # Comment the following line to send the "Cache-Tags" header to the client (e.g. to use CloudFlare cache tags) + unset resp.http.Cache-Tags; +} + +sub vcl_backend_response { + # Ban lurker friendly header + set beresp.http.url = bereq.url; + + # Add a grace in case the backend is down + set beresp.grace = 1h; +} diff --git a/api/helm/Chart.yaml b/api/helm/Chart.yaml index 858796cb..d9f49077 100644 --- a/api/helm/Chart.yaml +++ b/api/helm/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v1 appVersion: V.0.1 -description: Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar. -name: protocomponent +description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' +name: bs version: 0.1.0 -home: https://common-ground.dev -icon: https://common-ground.dev/logo-250x250.png \ No newline at end of file +home: pc.zaakonline.nl +icon: pc.zaakonline.nl \ No newline at end of file diff --git a/api/helm/templates/api-deployment.yaml b/api/helm/templates/api-deployment.yaml index 28a49457..11cca3fb 100644 --- a/api/helm/templates/api-deployment.yaml +++ b/api/helm/templates/api-deployment.yaml @@ -1,36 +1,37 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx + name: {{ include "name" . }}-nginx labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: replicas: 1 template: metadata: labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: containers: - - name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx + - name: {{ include "name" . }}-nginx image: "{{ .Values.settings.registryBase }}/{{ .Values.settings.projectName }}-nginx:{{ .Values.settings.env }}" imagePullPolicy: {{ .Values.settings.pullPolicy }} ports: - containerPort: 80 env: - name: PHP_SERVICE - valueFrom: - configMapKeyRef: - name: {{ template "fullname" . }} - key: php-service + value: {{ include "name" . }}-php + - name: NGINX_HOST + value: {{ include "name" . }}-php + - name: BACKENDS + value: {{ include "name" . }}-php resources: {{ toYaml .Values.resources | indent 12 }} {{- if .Values.nodeSelector }} diff --git a/api/helm/templates/api-loadbalancer.yaml b/api/helm/templates/api-loadbalancer.yaml index 770eb5bd..67a2f44a 100644 --- a/api/helm/templates/api-loadbalancer.yaml +++ b/api/helm/templates/api-loadbalancer.yaml @@ -2,11 +2,11 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-api-loadbalancer + name: {{ include "name" . }}-api-loadbalancer spec: selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/instance: {{ .Release.Name }} type: LoadBalancer ports: - protocol: TCP diff --git a/api/helm/templates/api-service.yaml b/api/helm/templates/api-service.yaml index 5eaba6fb..321b9345 100644 --- a/api/helm/templates/api-service.yaml +++ b/api/helm/templates/api-service.yaml @@ -1,12 +1,12 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-api + name: {{ include "name" . }} labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-api - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }} + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: NodePort @@ -15,5 +15,5 @@ spec: targetPort: 80 protocol: TCP selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-nginx - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-nginx + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/api/helm/templates/cert-issuer.yaml b/api/helm/templates/cert-issuer.yaml new file mode 100644 index 00000000..804486a2 --- /dev/null +++ b/api/helm/templates/cert-issuer.yaml @@ -0,0 +1,16 @@ +apiVersion: cert-manager.io/v1alpha2 +kind: ClusterIssuer +metadata: + name: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt +spec: + acme: + email: {{ .Values.settings.email }} + http01: {} + privateKeySecretRef: + name: letsencrypt-private-key + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - selector: {} + http01: + ingress: + class: nginx \ No newline at end of file diff --git a/api/helm/templates/certificate.yaml b/api/helm/templates/certificate.yaml new file mode 100644 index 00000000..78415e0d --- /dev/null +++ b/api/helm/templates/certificate.yaml @@ -0,0 +1,24 @@ +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: {{ include "name" . }}-{{ .Values.settings.env }}-cert +spec: + secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert + duration: 24h + renewBefore: 12h + dnsNames: +# {{- if eq .Values.settings.env "prod" }} +# - {{ .Values.settings.name }}.{{ .Values.settings.domain }} +# {{- else }} +# - {{ .Values.settings.name }}.{{ .Values.settings.env }}.{{ .Values.settings.domain }} +# {{- end }} +{{- range .Values.settings.domains }} + {{- if eq $.Values.settings.env "prod" }} + - {{ $.Values.settings.name }}.{{ . }} + {{- else }} + - {{ $.Values.settings.name }}.{{ $.Values.settings.env }}.{{ . }} + {{- end }} +{{- end }} + issuerRef: + name: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt + kind: ClusterIssuer \ No newline at end of file diff --git a/api/helm/templates/configmap.yaml b/api/helm/templates/configmap.yaml index d691cc9f..77e68c78 100644 --- a/api/helm/templates/configmap.yaml +++ b/api/helm/templates/configmap.yaml @@ -2,23 +2,43 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ template "fullname" . }} - namespace: {{ .Values.settings.env }} + #namespace: {{ .Values.settings.env }} labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }} - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }} + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} data: project_name: {{ .Values.settings.projectName | quote }} + app-name: {{ .Values.settings.name | quote }} + app-title: {{ .Values.settings.title | quote }} + app-version: {{ .Values.settings.version | quote }} + app-repro: {{ .Values.settings.repro | quote }} + app-demo: {{ .Values.settings.demo | quote }} + app-domains: {{ .Values.settings.domains | quote }} + app-domains-json: {{ .Values.settings.domainsJson | quote }} + app-description: {{ .Values.settings.description | quote }} + + app-auth: {{ .Values.settings.authorisationEnabled | quote }} + app-audittrail: {{ .Values.settings.audittrailEnabled | quote }} + app-notification: {{ .Values.settings.notificationEnabled | quote }} + app-health: {{ .Values.settings.healthEnabled | quote }} + app-archive: {{ .Values.settings.archiveEnabled | quote }} + + organization-name: {{ .Values.settings.organisationName | quote }} + organization-email: {{ .Values.settings.email | quote }} + organization-country: {{ .Values.settings.country | quote }} + organization-state: {{ .Values.settings.state | quote }} + organization-locality: {{ .Values.settings.locality | quote }} + organization-unit: {{ .Values.settings.unit | quote }} + env: {{ .Values.settings.env | quote }} debug: {{ .Values.settings.debug | quote }} cors-allow-origin: {{ .Values.settings.corsAllowOrigin | quote }} trusted-proxies: {{ join "," .Values.settings.trustedProxies }} trusted-hosts: {{ .Values.settings.trustedHosts | quote }} - project-name: {{ .Values.settings.projectName | quote }} - php-service: {{ include "name" . }}-{{ .Values.settings.env }}-php - + php-service: {{ include "name" . }}-{{ .Values.settings.env }}-php varnish-url: {{ if .Values.varnish.enabled }}http://varnish{{ else }}{{ .Values.varnish.url | quote }}{{ end }} mercure-publish-url: {{ .Values.mercure.publishUrl | quote }} mercure-subscribe-url: {{ .Values.mercure.subscribeUrl | quote }} diff --git a/api/helm/templates/ingress.yaml b/api/helm/templates/ingress.yaml index 4019c797..a684f9fc 100644 --- a/api/helm/templates/ingress.yaml +++ b/api/helm/templates/ingress.yaml @@ -1,35 +1,40 @@ apiVersion: extensions/v1beta1 kind: Ingress metadata: - name: {{ template "fullname" . }}-{{ .Values.settings.env }} + annotations: + # add an annotation indicating the issuer to use. + cert-manager.io/acme-challenge-type: http01 + cert-manager.io/cluster-issuer: {{ include "name" . }}-{{ .Values.settings.env }}-letsencrypt + name: {{ include "name" . }}-{{ .Values.settings.env }}-ingress labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-ingress - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-ingress + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} - {{- with .Values.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} spec: -{{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ .host | quote }} - {{- end }} - secretName: {{ .secretName }} + tls: + - hosts: + {{- range .Values.settings.domains }} + - {{ . }} {{- end }} -{{- end }} +# - {{ .Values.settings.domain }} + secretName: {{ include "name" . }}-{{ .Values.settings.env }}-cert rules: - {{- range .Values.ingress.hosts }} - - host: {{ .host | quote }} + {{- range .Values.settings.domains }} + {{- if eq $.Values.settings.env "prod" }} + - host: {{ $.Values.settings.name }}.{{ . }} + http: + paths: + - backend: + serviceName: {{ $.Values.settings.name }} + servicePort: 80 + {{- else }} + - host: {{ $.Values.settings.name }}.{{ $.Values.settings.env }}.{{ . }} http: paths: - - path: /* - backend: - serviceName: {{ .serviceName }} - servicePort: {{ .servicePort | default 80 }} + - backend: + serviceName: {{ $.Values.settings.name }} + servicePort: 80 + {{- end }} {{- end }} diff --git a/api/helm/templates/php-deployment.yaml b/api/helm/templates/php-deployment.yaml index 4baa30aa..347f1381 100644 --- a/api/helm/templates/php-deployment.yaml +++ b/api/helm/templates/php-deployment.yaml @@ -1,26 +1,26 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-php + name: {{ include "name" . }}-php labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: - replicas: {{ .Values.php.replicaCount }} + replicas: 1 template: metadata: labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: containers: - - name: {{ include "name" . }}-{{ .Values.settings.env }}-php + - name: {{ include "name" . }}-php image: "{{ .Values.settings.registryBase }}/{{ .Values.settings.projectName }}-php:{{ .Values.settings.env }}" imagePullPolicy: {{ .Values.settings.pullPolicy }} ports: @@ -46,7 +46,22 @@ spec: valueFrom: configMapKeyRef: name: {{ template "fullname" . }} - key: project-name + key: app-name + - name: APP_TITLE + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-title + - name: APP_DESCRIPTION + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-description + - name: APP_VERSION + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-version - name: APP_ENV valueFrom: configMapKeyRef: @@ -57,16 +72,77 @@ spec: configMapKeyRef: name: {{ template "fullname" . }} key: debug - - name: CORS_ALLOW_ORIGIN + - name: APP_DEMO valueFrom: configMapKeyRef: name: {{ template "fullname" . }} - key: cors-allow-origin - - name: VARNISH_URL + key: app-demo + # organization + - name: ORGANIZATION_NAME + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-name + - name: ORGANIZATION_EMAIL_ADDRESS + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-email + - name: ORGANIZATION_COUNTRY_NAME + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-country + - name: ORGANIZATION_STATE + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-state + - name: ORGANIZATION_LOCALITY valueFrom: configMapKeyRef: name: {{ template "fullname" . }} - key: varnish-url + key: organization-locality + - name: ORGANIZATION_UNIT_NAME + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: organization-unit + # config + - name: AUTH_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-auth + - name: AUDITTRAIL_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-audittrail + - name: NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-notification + - name: HEALTH_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-health + - name: ARCHIVE_ENABLED + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: app-archive + + # bla bla + - name: CORS_ALLOW_ORIGIN + valueFrom: + configMapKeyRef: + name: {{ template "fullname" . }} + key: cors-allow-origin + - name: VARNISH_URL + value: {{ include "name" . }}-varnish - name: APP_SECRET valueFrom: secretKeyRef: diff --git a/api/helm/templates/php-service.yaml b/api/helm/templates/php-service.yaml index ce957939..7f213a47 100644 --- a/api/helm/templates/php-service.yaml +++ b/api/helm/templates/php-service.yaml @@ -1,17 +1,17 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-php + name: {{ include "name" . }}-php labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: ClusterIP ports: - port: 9000 selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-php - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-php + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/api/helm/templates/varnish-deployment.yaml b/api/helm/templates/varnish-deployment.yaml index 87a4bcb7..5e41a9b4 100644 --- a/api/helm/templates/varnish-deployment.yaml +++ b/api/helm/templates/varnish-deployment.yaml @@ -2,19 +2,19 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish + name: {{ include "name" . }}-varnish labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-varnish + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: replicas: {{ .Values.varnish.replicaCount }} template: metadata: labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish + app.kubernetes.io/name: {{ include "name" . }}-varnish helm.sh/chart: {{ include "chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} @@ -23,18 +23,13 @@ spec: - name: {{ include "name" . }}-varnish image: "{{ .Values.settings.registryBase }}/{{ .Values.settings.projectName }}-varnish:{{ .Values.settings.env }}" imagePullPolicy: {{ .Values.settings.pullPolicy }} - command: ["varnishd"] - args: ["-F", "-f", "/usr/local/etc/varnish/default.vcl", "-p", "http_resp_hdr_len=65536", "-p", "http_resp_size=98304"] + env: + - name: BACKENDS + value: {{ include "name" . }}-php + #command: ["varnishd"] + #args: ["-F", "-f", "/usr/local/etc/varnish/default.vcl", "-p", "http_resp_hdr_len=65536", "-p", "http_resp_size=98304"] ports: - containerPort: 80 - livenessProbe: - httpGet: - path: /healthz - port: 80 - readinessProbe: - httpGet: - path: /healthz - port: 80 resources: {{ toYaml .Values.resources | indent 12 }} {{- if .Values.nodeSelector }} diff --git a/api/helm/templates/varnish-service.yaml b/api/helm/templates/varnish-service.yaml index 9c90c4da..7943479f 100644 --- a/api/helm/templates/varnish-service.yaml +++ b/api/helm/templates/varnish-service.yaml @@ -2,12 +2,12 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish + name: {{ include "name" . }}-varnish labels: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish - app.kubernetes.io/part-of: {{ include "name" . }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-varnish + app.kubernetes.io/part-of: {{ include "name" . }} helm.sh/chart: {{ include "chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: NodePort @@ -16,6 +16,6 @@ spec: targetPort: 80 protocol: TCP selector: - app.kubernetes.io/name: {{ include "name" . }}-{{ .Values.settings.env }}-varnish - app.kubernetes.io/instance: {{ .Release.Name }}-{{ .Values.settings.env }} + app.kubernetes.io/name: {{ include "name" . }}-varnish + app.kubernetes.io/instance: {{ .Release.Name }} {{- end -}} diff --git a/api/helm/values.yaml b/api/helm/values.yaml index b53a056a..9d8c1621 100644 --- a/api/helm/values.yaml +++ b/api/helm/values.yaml @@ -4,24 +4,48 @@ settings: registryBase: docker.io/conduction - projectName: pc + projectName: bs + name: bs + title: Berichten Service + version: V.0.1 + description: ''Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.'' + repro: 'https://github.com/ConductionNL/Proto-component-commonground' + subdomain: pc + domains: + - conduction.nl + - zaakonline.nl + - huwelijksplanner.online + - common-ground.dev + domainsJson: ["conduction.nl","zaakonline.nl","huwelijksplanner.online","common-ground.dev"] + organisationName: Conduction + email: info@conduction.nl + country: Netherlands + state: Noord-Holland + locality: Amsterdam + unit: Common-Ground + demo: pc.zaakonline.nl env: dev debug: 1 replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?common-ground\.dev$|^(.+\.)?zaakonline\.nl$|^(.+\.)?conduction\.nl$|^example\.com$|^(.+\.)?178.128.142.152$|178.128.142.152|localhost' + trustedHosts: '^(.+\.)?conduction\.nl$|^(.+\.)?huwelijksplanner\.online$|^(.+\.)?larping\.eu$|^(.+\.)?common-ground\.dev$|^(.+\.)?trouwplanner\.online$|^(.+\.)?zaakonline\.nl$|localhost' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 - # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer loadbalancerEnabled: false # If you want to enable NLX you are requered to add the appropreate certificates to you nlx-settings folder (located in the /api folder) nlxInwayEnabled: false - nlxOutwayEnabled: true - + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + notificationEnabled: false + audittrailEnabled: false + authorisationEnabled: false + healthEnabled: false + archiveEnabled: false + php: repository: docker.io/conduction/protocomponent-php diff --git a/api/public/schema/openapi.yaml b/api/public/schema/openapi.yaml index 753a595d..2f4e8a23 100644 --- a/api/public/schema/openapi.yaml +++ b/api/public/schema/openapi.yaml @@ -1,553 +1,33 @@ openapi: 3.0.2 info: - title: 'Proto Component' + title: 'Berichten Service' version: V.0.1 description: | API Details - - Component: Proto Component - - Reference: pc + - Component: Berichten Service + - Reference: bs - Enviroment: dev - Version: V.0.1 - - Repository: []() / [zip](/archive/master.zip) - - Datamodel: [postman](/schema/openapi.postman_collection) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) + - Repository: [online](https://github.com/ConductionNL/Proto-component-commonground) / [zip](https://github.com/ConductionNL/Proto-component-commonground/archive/master.zip) + - Docker Image: [online](https://hub.docker.com/repository/docker/conduction/bs-php) + - Datamodel: [postman](/schema/bs.postman_collection.json) / [oas](/schema/openapi.yaml) / [pdf](/schema/datamodel.pdf) / [mwb](/schema/datamodel.mwb) - Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar. - - Voor het gebruik van deze applicatie is een JWT Token nodig, deze hangt altijd vast aan een applicatie, ofwel user. Geldige JWT Tokens worden aangemaakt bij het registreren van een applicatie en kennen een beperkte houdbaarheid. - JWT Tokens kunnen zowel worden verlengd, als opnieuw worden aangevraagd, dit aan de hand van de applicatie id en sleutel. - Let er bij het meegeven van JWT tokens op dat deze moet worden voorafgegaan door een Bearer en een spatie, onder de header Authorization. De volledig naam wordt daarmee: 'Authorization: Bearer [TOKEN]'. + 'Naast deze JSON rest API is er ook een [graphql](/graphql) interface beschikbaar.' -paths: - /example_entities: - get: - tags: - - ExampleEntity - operationId: getExampleEntityCollection - summary: 'Retrieves the collection of ExampleEntity resources.' - responses: - 200: - description: 'ExampleEntity collection response' - content: - application/hal+json: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - type: array - items: - $ref: '#/components/schemas/ExampleEntity' - parameters: - - - name: like_name - in: query - required: false - schema: - type: string - - - name: like_description - in: query - required: false - schema: - type: string - - - name: page - in: query - required: false - description: 'The collection page number' - schema: - type: integer - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - post: - tags: - - ExampleEntity - operationId: postExampleEntityCollection - summary: 'Creates a ExampleEntity resource.' - responses: - 201: - description: 'ExampleEntity resource created' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity' - links: - GetExampleEntityItem: - parameters: - id: '$response.body#/id' - operationId: getExampleEntityItem - description: 'The `id` value returned in the response can be used as the `id` parameter in `GET /example_entities/{id}`.' - 400: - description: 'Invalid input' - 404: - description: 'Resource not found' - requestBody: - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity' - description: 'The new ExampleEntity resource' - parameters: - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - '/example_entities/{id}': - get: - tags: - - ExampleEntity - operationId: getExampleEntityItem - summary: 'Retrieves a ExampleEntity resource.' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - responses: - 200: - description: 'ExampleEntity resource response' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity' - 404: - description: 'Resource not found' - delete: - tags: - - ExampleEntity - operationId: deleteExampleEntityItem - summary: 'Removes the ExampleEntity resource.' - responses: - 204: - description: 'ExampleEntity resource deleted' - 404: - description: 'Resource not found' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - put: - tags: - - ExampleEntity - operationId: putExampleEntityItem - summary: 'Replaces the ExampleEntity resource.' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - responses: - 200: - description: 'ExampleEntity resource updated' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity' - 400: - description: 'Invalid input' - 404: - description: 'Resource not found' - requestBody: - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity' - description: 'The updated ExampleEntity resource' - patch: - tags: - - ExampleEntity - operationId: patchExampleEntityItem - summary: 'Updates the ExampleEntity resource.' - parameters: - - - name: id - in: path - required: true - schema: - type: string - - - name: Authorization - description: 'The JWT of the entity performing the request' - in: header - - - name: API-Version - description: 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)' - example: 1.0.1 - in: header - - - name: X-NLX-Logrecord-ID - description: 'A globally unique id of the request, which makes a request traceable throughout the network.' - in: header - - - name: X-NLX-Request-Process-Id - description: 'A process id for purpose registration (doelbinding)' - in: header - - - name: X-NLX-Request-Data-Elements - description: 'A list of requested data elements' - in: header - - - name: X-NLX-Request-Data-Subject - description: 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`' - in: header - - - name: X-Audit-Clarification - description: 'A clarification as to why a request has been made (doelbinding)' - in: header - responses: - 200: - description: 'ExampleEntity resource updated' - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity' - 400: - description: 'Invalid input' - 404: - description: 'Resource not found' - requestBody: - content: - application/hal+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/ld+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/vnd.api+json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/json: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/xml: - schema: - $ref: '#/components/schemas/ExampleEntity' - application/x-yaml: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/csv: - schema: - $ref: '#/components/schemas/ExampleEntity' - text/html: - schema: - $ref: '#/components/schemas/ExampleEntity' - description: 'The updated ExampleEntity resource' -components: - schemas: - ExampleEntity: - type: object - description: '' - properties: - id: - readOnly: true - type: integer - name: - type: string - description: - type: string +paths: { } +definitions: [] +tags: [] +securityDefinitions: + JWT-Oauth: + type: oauth2 + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + flow: implicit + scopes: [] + JWT-Token: + type: apiKey + in: header + name: Authorization + scopes: [] host: irc.zaakonline.nl servers: - diff --git a/api/public/schema/publiccode.yaml b/api/public/schema/publiccode.yaml new file mode 100644 index 00000000..757ee744 --- /dev/null +++ b/api/public/schema/publiccode.yaml @@ -0,0 +1,116 @@ +publiccodeYmlVersion: "0.2" + +name: bs +applicationSuite: commonground +url: "https://github.com/ConductionNL/Proto-component-commonground" +landingURL: "pc.zaakonline.nl" +isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" +softwareVersion: "V.0.1" +releaseDate: "2020-10-01" +logo: pc.zaakonline.nl +monochromeLogo: img/logo-mono.svg + +inputTypes: + - application/json + - application/xml + +outputTypes: + - application/json + - application/ld+json + - application/hal+json + - application/vnd.api+json + - application/health+json + - application/xml + - application/x-yaml + - text/csv + - text/html + +platforms: + - web + +categories: + - it-development + +usedBy: + - Gemeente Utrecht + - Gemeente Den Haag + - Gemeente Hoorn + + +roadmap: "https://github.com/ConductionNL/Proto-component-commonground/blob/master/ROADMAP.md" + +developmentStatus: development + +softwareType: "standalone/other" + +#intendedAudience: +# scope: +# - science-and-technology +# countries: +# - it +# - de +# unsupportedCountries: +# - us + +description: + en: +# localisedName: Medusa +# genericName: Text Editor +# shortDescription: > +# This description can have a maximum 150 +# characters long. We should not fill the +# remaining space with "Lorem Ipsum". End +# +# longDescription: > +# Very long description of this software, also split +# on multiple rows. You should note what the software +# is and why one should need it. + + documentation: "https://github.com/ConductionNL/Proto-component-commonground/blob/master/README.md" + apiDocumentation: "pc.zaakonline.nl" +# +# features: +# - Very important feature +# - Will run without a problem +# - Has zero bugs +# - Solves all the problems of the world +# screenshots: +# - img/sshot1.jpg +# - img/sshot2.jpg +# - img/sshot3.jpg +# videos: +# - https://youtube.com/xxxxxxxx +# awards: +# - 1st Price Software of the year + +legal: + license: EUPL-1.2 + mainCopyrightOwner: Conduction + repoOwner: Conduction + authorsFile: AUTHORS.md + +maintenance: + type: "internal" + + contractors: + - name: "Conduction B.V" + email: "info@conduction.nl" + website: "https://www.conduction.nl" + until: "2099-01-01" + + contacts: + - name: Ruben van der Linde + email: "ruben@conduction.nl" + affiliation: "Conduction B.V" + +localisation: + localisationReady: yes + availableLanguages: + - en + - nl + +dependsOn: + open: + - name: Kubernetes + versionMin: "1.15.5-do.1" + diff --git a/api/src/Command/ApiHelmCommand.php b/api/src/Command/ApiHelmCommand.php index 6bac5366..0caa16f6 100644 --- a/api/src/Command/ApiHelmCommand.php +++ b/api/src/Command/ApiHelmCommand.php @@ -1,5 +1,7 @@ twig= $twig; - - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('app:helm:update') - // the short description shown while running "php bin/console list" - ->setDescription('Creates a new helm chart.') - - // the full command description shown when running the command with - // the "--help" option - ->setHelp('This command allows you to create a new hel chart from the helm template') - ->setAliases(['app:helm:export']) - ->setDescription('Dump the OpenAPI documentation') - ->addOption('location', null, InputOption::VALUE_OPTIONAL, 'Write output to files in the given location','/srv/api/helm') - ->addOption('spec-version', null, InputOption::VALUE_OPTIONAL, 'Helm version to use ("0.1.0")', '0.1.0') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $io = new SymfonyStyle($input, $output); - /** @var string $version */ - $version = $input->getOption('spec-version'); - - //if (!\in_array($version, ['0.1.0'], true)) { - // throw new InvalidOptionException(sprintf('This tool only supports version 2 and 3 of the OpenAPI specification ("%s" given).', $version)); - //} - - $values = $this->twig->render('helm/Values.yaml.twig'); - $chart = $this->twig->render('helm/Chart.yaml.twig'); - - - if (!empty($location= $input->getOption('location')) && \is_string($location)) { - file_put_contents($location.'/values.yaml', $values); - file_put_contents($location.'/Chart.yaml', $chart); - $io->success(sprintf('Data written to %s (specification version %s).', $location, $version)); - } else { - // outputs multiple lines to the console (adding "\n" at the end of each line) - $output->writeln([ - 'Helm Chart Creator', - '============', - $chart, - ]); - } - } + private $twig; + + public function __construct(Environment $twig) + { + $this->twig = $twig; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('app:helm:update') + // the short description shown while running "php bin/console list" + ->setDescription('Creates a new helm chart.') + + // the full command description shown when running the command with + // the "--help" option + ->setHelp('This command allows you to create a new hel chart from the helm template') + ->setAliases(['app:helm:export']) + ->setDescription('Dump the OpenAPI documentation') + ->addOption('location', null, InputOption::VALUE_OPTIONAL, 'Write output to files in the given location', '/srv/api/helm') + ->addOption('spec-version', null, InputOption::VALUE_OPTIONAL, 'Helm version to use ("0.1.0")', '0.1.0'); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + /** @var string $version */ + $version = $input->getOption('spec-version'); + + //if (!\in_array($version, ['0.1.0'], true)) { + // throw new InvalidOptionException(sprintf('This tool only supports version 2 and 3 of the OpenAPI specification ("%s" given).', $version)); + //} + + $values = $this->twig->render('helm/Values.yaml.twig'); + $chart = $this->twig->render('helm/Chart.yaml.twig'); + + if (!empty($location = $input->getOption('location')) && \is_string($location)) { + file_put_contents($location.'/values.yaml', $values); + file_put_contents($location.'/Chart.yaml', $chart); + $io->success(sprintf('Data written to %s (specification version %s).', $location, $version)); + } else { + // outputs multiple lines to the console (adding "\n" at the end of each line) + $output->writeln([ + 'Helm Chart Creator', + '============', + $chart, + ]); + } + } } diff --git a/api/src/Command/PubliccodeCommand.php b/api/src/Command/PubliccodeCommand.php new file mode 100644 index 00000000..75c24371 --- /dev/null +++ b/api/src/Command/PubliccodeCommand.php @@ -0,0 +1,71 @@ +twig = $twig; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('app:publiccode:update') + // the short description shown while running "php bin/console list" + ->setDescription('Creates a new public chart.') + + // the full command description shown when running the command with + // the "--help" option + ->setHelp('see ehttps://github.com/italia/publiccode.yml') + ->setDescription('Publiccode.yml is a metadata standard for repositories containing software developed or acquired by the Public Administration, aimed at making them easily discoverabile and thus reusable by other entities.By including a publiccode.yml file in the root of a repository, and populating it with information about the software, technicians and civil servants can evaluate it. Automatic indexing tools can also be built, since the format is easily readable by both humans and machines.') + ->addOption('location', null, InputOption::VALUE_OPTIONAL, 'Write output to files in the given location', '/srv/api/public/schema/') + ->addOption('spec-version', null, InputOption::VALUE_OPTIONAL, 'Publiccode version to use ("0.1.0")', '0.1.0'); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + /** @var string $version */ + $version = $input->getOption('spec-version'); + + //if (!\in_array($version, ['0.1.0'], true)) { + // throw new InvalidOptionException(sprintf('This tool only supports version 2 and 3 of the OpenAPI specification ("%s" given).', $version)); + //} + + $publiccode = $this->twig->render('publiccode/publiccode.yaml.twig'); + + if (!empty($location = $input->getOption('location')) && \is_string($location)) { + file_put_contents($location.'/publiccode.yaml', $publiccode); + $io->success(sprintf('Data written to %s/publiccode.yaml (specification version %s).', $location, $version)); + } else { + // outputs multiple lines to the console (adding "\n" at the end of each line) + $output->writeln([ + 'Publiccode Chart', + '============', + $chart, + ]); + } + } +} diff --git a/api/src/Entity/ExampleEntity.php b/api/src/Entity/ExampleEntity.php deleted file mode 100644 index f63f7a99..00000000 --- a/api/src/Entity/ExampleEntity.php +++ /dev/null @@ -1,71 +0,0 @@ -id; - } - - public function getName(): ?string - { - return $this->name; - } - - public function setName(string $name): self - { - $this->name = $name; - - return $this; - } - - public function getDescription(): ?string - { - return $this->description; - } - - public function setDescription(?string $description): self - { - $this->description = $description; - - return $this; - } - -} diff --git a/api/src/Entity/NLXRequestLog.php b/api/src/Entity/NLXRequestLog.php index c3c3a1c4..1d886b85 100644 --- a/api/src/Entity/NLXRequestLog.php +++ b/api/src/Entity/NLXRequestLog.php @@ -235,12 +235,12 @@ public function setEndpoint(string $endpoint): self public function getMethod(): ?string { - return $this->method; + return $this->method; } public function setMethod(string $method): self { - $this->method = $method; + $this->method = $method; return $this; } diff --git a/api/src/Filter/LikeFilter.php b/api/src/Filter/LikeFilter.php index 1496dd18..029c73e9 100644 --- a/api/src/Filter/LikeFilter.php +++ b/api/src/Filter/LikeFilter.php @@ -1,4 +1,5 @@ isPropertyEnabled($property, $resourceClass) || - !$this->isPropertyMapped($property, $resourceClass) - ) { - return; - } - - $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters - $queryBuilder - ->andWhere(sprintf('o.%s LIKE :%s', $property, $parameterName)) - ->setParameter($parameterName, $value); - } - - // This function is only used to hook in documentation generators (supported by Swagger and Hydra) - public function getDescription(string $resourceClass): array - { - if (!$this->properties) { - return []; - } - - $description = []; - foreach ($this->properties as $property => $strategy) { - $description["like_$property"] = [ - 'property' => $property, - 'type' => 'string', - 'required' => false, - 'swagger' => [ - 'description' => 'This filter narows your result using the * and _ wildcards, where * is assumed to be one or more characters and _ is assumed to be a single character', - 'name' => $property, - 'type' => 'string', - ], - ]; - } - - return $description; - } -} \ No newline at end of file + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) + { + // otherwise filter is applied to order and page as well + if ( + !$this->isPropertyEnabled($property, $resourceClass) || + !$this->isPropertyMapped($property, $resourceClass) + ) { + return; + } + + $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters + $queryBuilder + ->andWhere(sprintf('o.%s LIKE :%s', $property, $parameterName)) + ->setParameter($parameterName, $value); + } + + // This function is only used to hook in documentation generators (supported by Swagger and Hydra) + public function getDescription(string $resourceClass): array + { + if (!$this->properties) { + return []; + } + + $description = []; + foreach ($this->properties as $property => $strategy) { + $description["like_$property"] = [ + 'property' => $property, + 'type' => 'string', + 'required' => false, + 'swagger' => [ + 'description' => 'This filter narows your result using the * and _ wildcards, where * is assumed to be one or more characters and _ is assumed to be a single character', + 'name' => $property, + 'type' => 'string', + ], + ]; + } + + return $description; + } +} diff --git a/api/src/Filter/RegexpFilter.php b/api/src/Filter/RegexpFilter.php index ffda6ff7..da1f747e 100644 --- a/api/src/Filter/RegexpFilter.php +++ b/api/src/Filter/RegexpFilter.php @@ -1,4 +1,5 @@ isPropertyEnabled($property, $resourceClass) || - !$this->isPropertyMapped($property, $resourceClass) - ) { - return; - } - - $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters - $queryBuilder - ->andWhere(sprintf('REGEXP(o.%s, :%s) = 1', $property, $parameterName)) - ->setParameter($parameterName, $value); - } - - // This function is only used to hook in documentation generators (supported by Swagger and Hydra) - public function getDescription(string $resourceClass): array - { - if (!$this->properties) { - return []; - } - - $description = []; - foreach ($this->properties as $property => $strategy) { - $description["regexp_$property"] = [ - 'property' => $property, - 'type' => 'string', - 'required' => false, - 'swagger' => [ - 'description' => 'Filter for an exact match using a [Regular expression](https://en.wikipedia.org/wiki/Regular_expression).', - 'name' => $property, - 'type' => 'string', - ], - ]; - } - - return $description; - } -} \ No newline at end of file + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) + { + // otherwise filter is applied to order and page as well + if ( + !$this->isPropertyEnabled($property, $resourceClass) || + !$this->isPropertyMapped($property, $resourceClass) + ) { + return; + } + + $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters + $queryBuilder + ->andWhere(sprintf('REGEXP(o.%s, :%s) = 1', $property, $parameterName)) + ->setParameter($parameterName, $value); + } + + // This function is only used to hook in documentation generators (supported by Swagger and Hydra) + public function getDescription(string $resourceClass): array + { + if (!$this->properties) { + return []; + } + + $description = []; + foreach ($this->properties as $property => $strategy) { + $description["regexp_$property"] = [ + 'property' => $property, + 'type' => 'string', + 'required' => false, + 'swagger' => [ + 'description' => 'Filter for an exact match using a [Regular expression](https://en.wikipedia.org/wiki/Regular_expression).', + 'name' => $property, + 'type' => 'string', + ], + ]; + } + + return $description; + } +} diff --git a/api/src/Repository/ExampleEntityRepository.php b/api/src/Repository/ExampleEntityRepository.php index 7baa698c..692bece7 100644 --- a/api/src/Repository/ExampleEntityRepository.php +++ b/api/src/Repository/ExampleEntityRepository.php @@ -4,7 +4,7 @@ use App\Entity\ExampleEntity; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Symfony\Bridge\Doctrine\RegistryInterface; +use Doctrine\Common\Persistence\ManagerRegistry; /** * @method ExampleEntity|null find($id, $lockMode = null, $lockVersion = null) @@ -14,7 +14,7 @@ */ class ExampleEntityRepository extends ServiceEntityRepository { - public function __construct(RegistryInterface $registry) + public function __construct(ManagerRegistry $registry) { parent::__construct($registry, ExampleEntity::class); } diff --git a/api/src/Repository/NLXRequestLogRepository.php b/api/src/Repository/NLXRequestLogRepository.php index ed8d0a95..69add53c 100644 --- a/api/src/Repository/NLXRequestLogRepository.php +++ b/api/src/Repository/NLXRequestLogRepository.php @@ -4,7 +4,8 @@ use App\Entity\NLXRequestLog; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Symfony\Bridge\Doctrine\RegistryInterface; +use Doctrine\Common\Persistence\ManagerRegistry; + /** * @method NLXRequestLog|null find($id, $lockMode = null, $lockVersion = null) @@ -14,25 +15,24 @@ */ class NLXRequestLogRepository extends ServiceEntityRepository { - public function __construct(RegistryInterface $registry) - { - parent::__construct($registry, NLXRequestLog::class); - } + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, ExampleEntity::class); + } /** - * @return NLXRequestLog[] Returns an array of NLXRequestLog objects - */ + * @return NLXRequestLog[] Returns an array of NLXRequestLog objects + */ public function getLogEntries($entity) { - return $this->createQueryBuilder('l') - ->where('l.objectClass = :objectClass') - ->setParameter('objectClass', $this->getEntityManager()->getMetadataFactory()->getMetadataFor(get_class($entity))->getName()) - ->andWhere('l.objectId = :objectId') - ->setParameter('objectId', $entity->getId()) - ->orderBy('l.loggedAt', 'DESC') - ->getQuery() - ->getResult(); - + return $this->createQueryBuilder('l') + ->where('l.objectClass = :objectClass') + ->setParameter('objectClass', $this->getEntityManager()->getMetadataFactory()->getMetadataFor(get_class($entity))->getName()) + ->andWhere('l.objectId = :objectId') + ->setParameter('objectId', $entity->getId()) + ->orderBy('l.loggedAt', 'DESC') + ->getQuery() + ->getResult(); } /* diff --git a/api/src/Service/NLXLogService.php b/api/src/Service/NLXLogService.php index 24c5cff1..3f2d2e3c 100644 --- a/api/src/Service/NLXLogService.php +++ b/api/src/Service/NLXLogService.php @@ -1,4 +1,5 @@ em = $em; - } - + private $em; + + public function __construct(EntityManagerInterface $em) + { + $this->em = $em; + } } diff --git a/api/src/Subscriber/FieldsAndExtendSubscriber.php b/api/src/Subscriber/FieldsAndExtendSubscriber.php new file mode 100644 index 00000000..d50440c7 --- /dev/null +++ b/api/src/Subscriber/FieldsAndExtendSubscriber.php @@ -0,0 +1,135 @@ +params = $params; + $this->serializer = $serializer; + $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::VIEW => ['FilterFields', EventPriorities::PRE_SERIALIZE], + ]; + } + + public function FilterFields(GetResponseForControllerResultEvent $event) + { + /* @todo Contains a bug + $result = $event->getControllerResult(); + $fields = $event->getRequest()->query->get('fields'); + $extends = $event->getRequest()->query->get('extend'); + $contentType= $event->getRequest()->headers->get('accept'); + if(!$contentType){ + $contentType= $event->getRequest()->headers->get('Accept'); + } + + + // Only do somthing if fields is query supplied + if (!$fields && !$extends) { + return $result; + } + + // This needs to be bassed on the content-type + + // Lets set a return content type + switch ($contentType) { + case 'application/json': + $renderType = "json"; + break; + case 'application/ld+json': + $renderType= "jsonld"; + break; + case 'application/hal+json': + $renderType= "jsonhal"; + break; + default: + $contentType = 'application/json'; + $renderType = "json"; + } + + // let turn fields into an array if it isn't one already + if (!is_array($fields)) { + $fields = explode(',', $fields); + } + if (!is_array($extends)) { + $extends= explode(',', $extends); + } + + // Its possible to nest fields for filterins + foreach($fields as $key=>$value){ + // Lets check if the fields contain one or more .'s + if (strpos($value, '.') !== false) { + // This is where it gets complicated couse it could go on indevinitly + } + } + + // Overwrite maxdepth for extended properties + + // we always need to return an id and links (in order not to break stuff) + if (!in_array('id', $fields)) { + $fields[] = 'id'; + } + if (!in_array('_links', $fields)) { + $fields[] = '_links'; + } + + // now we need to overide the normal subscriber + $json = $this->serializer->serialize( + $result, + $renderType, + ['enable_max_depth' => true, + 'attributes'=> $fields] + ); + + + $jsonArray = json_decode($json, true); + + + // The we want to extend properties from the extend query + foreach($extends as $extend){ + // @todo add security checks + // Get new object for the extend + $extendObject = $this->propertyAccessor->getValue($result, $extend); + // turn to json + $extendjson = $this->serializer->serialize( + $result, + $type, + ['enable_max_depth' => true, + 'attributes'=> $fields] + ); + // add to the array + $jsonArray[$extend] = json_decode($extendjson, true); + } + + + $json = json_encode($jsonArray); + + $response = new Response( + $json, + Response::HTTP_OK, + ['content-type' => $contentType] + ); + + $event->setResponse($response); + */ + } +} diff --git a/api/src/Subscriber/FieldsSubscriber.php b/api/src/Subscriber/FieldsSubscriber.php deleted file mode 100644 index 1372fd99..00000000 --- a/api/src/Subscriber/FieldsSubscriber.php +++ /dev/null @@ -1,74 +0,0 @@ -params = $params; - $this->serializer= $serializer; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['FilterFields', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function FilterFields(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - $fields = $event->getRequest()->query->get('fields'); - - // Only do somthing if fields is query supplied - if (!$fields) { - return $result; - } - - // let turn fields into an array if it isn't one already - if(!is_array($fields)){ - $fields = explode(",", $fields); - } - - - // we always need to return an id and links (in order not to break stuff) - if(!in_array("id",$fields)){$fields[]='id';} - if(!in_array("_links",$fields)){$fields[]='_links';} - - // now we need to overide the normal subscriber - $json = $this->serializer->serialize( - $result, - 'jsonhal',['enable_max_depth' => true,'attributes'=> $fields] - ); - - $response = new Response( - $json, - Response::HTTP_OK, - ['content-type' => 'application/json+hal'] - ); - - $event->setResponse($response); - - return; - } -} diff --git a/api/src/Subscriber/LogSubscriber.php b/api/src/Subscriber/LogSubscriber.php deleted file mode 100644 index c58d7d1c..00000000 --- a/api/src/Subscriber/LogSubscriber.php +++ /dev/null @@ -1,84 +0,0 @@ -params = $params; - $this->em= $em; - $this->serializer= $serializer; - $this->annotationReader = $annotationReader; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['Log', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function Log(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - $showLogs= $event->getRequest()->query->get('showLogs'); - - // Lets see if this class has a Loggableannotation - $loggable = false; - $reflClass = new \ReflectionClass($result); - $annotations = $this->annotationReader->getClassAnnotations($reflClass); - - foreach($annotations as $annotation ){ - if(get_class($annotation) == "Gedmo\Mapping\Annotation\Loggable"){ - $loggable = true; - } - } - - // Only do somthing if we are on te log route and the entity is logable - /* @todo we should trhow errors here foruser feedback */ - if (!$showLogs || !$loggable) { - return $result; - } - - $repo = $this->em->getRepository('Gedmo\Loggable\Entity\LogEntry'); // we use default log entry class - $logs = $repo->getLogEntries($result); - - // now we need to overide the normal subscriber - $json = $this->serializer->serialize( - $logs, - 'jsonhal',['enable_max_depth' => true] - ); - - $response = new Response( - $json, - Response::HTTP_OK, - ['content-type' => 'application/json+hal'] - ); - - $event->setResponse($response); - - return; - } -} diff --git a/api/src/Subscriber/NLXSubscriber.php b/api/src/Subscriber/NLXSubscriber.php index d846884b..5411001e 100644 --- a/api/src/Subscriber/NLXSubscriber.php +++ b/api/src/Subscriber/NLXSubscriber.php @@ -2,118 +2,109 @@ namespace App\Subscriber; -use ApiPlatform\Core\Exception\InvalidArgumentException; use ApiPlatform\Core\EventListener\EventPriorities; +use App\Entity\NLXRequestLog; +use App\Service\NLXLogService; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Serializer\SerializerInterface; -use Doctrine\ORM\EntityManagerInterface; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; -use Symfony\Component\HttpFoundation\Session\Session; - - -use App\Service\NLXLogService; -use App\Entity\NLXRequestLog; class NLXSubscriber implements EventSubscriberInterface { - private $params; - private $em; - private $serializer; - private $nlxLogService; - - public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer,NLXLogService $nlxLogService) - { - $this->params = $params; - $this->em = $em; - $this->serializer = $serializer; - $this->nlxLogService = $nlxLogService; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['NLXLog', EventPriorities::PRE_VALIDATE], - KernelEvents::VIEW => ['NLXAudit', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function NLXAudit(GetResponseForControllerResultEvent $event){ - - $result = $event->getControllerResult(); - $auditTrail= $event->getRequest()->query->get('auditTrail'); - - // Only do somthing if we are on te log route and the entity is logable - /* @todo we should trhow errors here foruser feedback */ - if (!$auditTrail ) { - return $result; - } - - $repo = $this->em->getRepository('App\Entity\NLXRequestLog'); - $logs = $repo->getLogEntries($result); - - - // now we need to overide the normal subscriber - $json = $this->serializer->serialize( - $logs, - 'jsonhal',['enable_max_depth' => true] - ); - - $response = new Response( - $json, - Response::HTTP_OK, - ['content-type' => 'application/json+hal'] - ); - - $event->setResponse($response); - - return; - } - - - public function NLXLog(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - - $session = new Session(); - $session->start(); - // See: https://docs.nlx.io/further-reading/transaction-logs/ - - $log = New NLXRequestLog; - $log->setApplicationId ($event->getRequest()->headers->get('X-NLX-Application-Id')); - $log->setRequestId ($event->getRequest()->headers->get('X-NLX-Request-Id')); - $log->setUserId ($event->getRequest()->headers->get('X-NLX-Request-User-Id')); - $log->setSubjectId ($event->getRequest()->headers->get('X-NLX-Request-Subject-Identifier')); - $log->setProcessId ($event->getRequest()->headers->get('X-NLX-Request-Process-Id')); - $log->setDataElements ($event->getRequest()->headers->get('X-NLX-Request-Data-Elements')); - $log->setDataSubjects ($event->getRequest()->headers->get('X-NLX-Request-Data-Subject')); - $log->setObjectId ($result->getid()); - $log->setObjectClass ($this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()); - $log->setRoute ($event->getRequest()->attributes->get('_route')); - $log->setEndpoint ($event->getRequest()->getPathInfo()); - $log->setMethod ($event->getRequest()->getMethod()); - $log->setContentType ($event->getRequest()->headers->get('Content-Type')); - $log->setContent ($event->getRequest()->getContent()); - $log->setSession ($session->getId()); - $log->setLoggedAt (new \DateTime() ); - - $this->em->persist($log); - $this->em->flush($log); - - // $authorization = $this->params->get('nlx.components.authorization.'); - // We need to do serveral things for nlx - - // First of all we need to log this request to our audit trial, where at minimal level we need to log who (application) asked what (data) for wich reasons (goal). We also need to consider that the requestee might have used the field query parmeter. So we need to log what fields of the object where actually returned. - - // Then we need to authenticate the request against a common ground authentication component - - // In the current common ground we dont bother with authorization (every one may do anything as long as we know who it is) - - return $result; - } + private $params; + private $em; + private $serializer; + private $nlxLogService; + + public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer, NLXLogService $nlxLogService) + { + $this->params = $params; + $this->em = $em; + $this->serializer = $serializer; + $this->nlxLogService = $nlxLogService; + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::VIEW => ['NLXLog', EventPriorities::PRE_VALIDATE], + KernelEvents::VIEW => ['NLXAudit', EventPriorities::PRE_SERIALIZE], + ]; + } + + public function NLXAudit(GetResponseForControllerResultEvent $event) + { + $result = $event->getControllerResult(); + $auditTrail = $event->getRequest()->query->get('auditTrail'); + + // Only do somthing if we are on te log route and the entity is logable + /* @todo we should trhow errors here foruser feedback */ + if (!$auditTrail) { + return $result; + } + + $repo = $this->em->getRepository('App\Entity\NLXRequestLog'); + $logs = $repo->getLogEntries($result); + + // now we need to overide the normal subscriber + $json = $this->serializer->serialize( + $logs, + 'jsonhal', ['enable_max_depth' => true] + ); + + $response = new Response( + $json, + Response::HTTP_OK, + ['content-type' => 'application/json+hal'] + ); + + $event->setResponse($response); + } + + public function NLXLog(GetResponseForControllerResultEvent $event) + { + $result = $event->getControllerResult(); + + $session = new Session(); + $session->start(); + // See: https://docs.nlx.io/further-reading/transaction-logs/ + + $log = new NLXRequestLog(); + $log->setApplicationId($event->getRequest()->headers->get('X-NLX-Application-Id')); + $log->setRequestId($event->getRequest()->headers->get('X-NLX-Request-Id')); + $log->setUserId($event->getRequest()->headers->get('X-NLX-Request-User-Id')); + $log->setSubjectId($event->getRequest()->headers->get('X-NLX-Request-Subject-Identifier')); + $log->setProcessId($event->getRequest()->headers->get('X-NLX-Request-Process-Id')); + $log->setDataElements($event->getRequest()->headers->get('X-NLX-Request-Data-Elements')); + $log->setDataSubjects($event->getRequest()->headers->get('X-NLX-Request-Data-Subject')); + $log->setObjectId($result->getid()); + $log->setObjectClass($this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()); + $log->setRoute($event->getRequest()->attributes->get('_route')); + $log->setEndpoint($event->getRequest()->getPathInfo()); + $log->setMethod($event->getRequest()->getMethod()); + $log->setContentType($event->getRequest()->headers->get('Content-Type')); + $log->setContent($event->getRequest()->getContent()); + $log->setSession($session->getId()); + $log->setLoggedAt(new \DateTime()); + + $this->em->persist($log); + $this->em->flush($log); + + // $authorization = $this->params->get('nlx.components.authorization.'); + // We need to do serveral things for nlx + + // First of all we need to log this request to our audit trial, where at minimal level we need to log who (application) asked what (data) for wich reasons (goal). We also need to consider that the requestee might have used the field query parmeter. So we need to log what fields of the object where actually returned. + + // Then we need to authenticate the request against a common ground authentication component + + // In the current common ground we dont bother with authorization (every one may do anything as long as we know who it is) + + return $result; + } } diff --git a/api/src/Subscriber/ValidOnSubscriber.php b/api/src/Subscriber/ValidOnSubscriber.php index 220b5288..4aac9f15 100644 --- a/api/src/Subscriber/ValidOnSubscriber.php +++ b/api/src/Subscriber/ValidOnSubscriber.php @@ -2,105 +2,96 @@ namespace App\Subscriber; -use ApiPlatform\Core\Exception\InvalidArgumentException; use ApiPlatform\Core\EventListener\EventPriorities; +use Doctrine\Common\Annotations\Reader; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Serializer\SerializerInterface; -use Doctrine\ORM\EntityManagerInterface; -use Doctrine\Common\Annotations\Reader; -use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; - -use App\Service\RequestService; class ValidOnSubscriber implements EventSubscriberInterface { - private $params; - private $em; - private $serializer; - private $annotationReader; - - public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer, Reader $annotationReader) - { - $this->params = $params; - $this->em= $em; - $this->serializer= $serializer; - $this->annotationReader = $annotationReader; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::VIEW => ['validOn', EventPriorities::PRE_SERIALIZE], - ]; - - } - - public function validOn(GetResponseForControllerResultEvent $event) - { - $result = $event->getControllerResult(); - - // Lets get validOn from the query but deafult back to geldig op (for backward compatibality with api standaard) - $geldigOp = $event->getRequest()->query->get('geldigOp', false); - $validOn = $event->getRequest()->query->get('validOn', $geldigOp); - - // Lets see if this class has a Loggableannotation - $loggable = false; - $reflClass = new \ReflectionClass($result); - $annotations = $this->annotationReader->getClassAnnotations($reflClass); - - foreach($annotations as $annotation ){ - if(get_class($annotation) == "Gedmo\Mapping\Annotation\Loggable"){ - $loggable = true; - } - } - - // Only do somthing if fields is query supplied - if (!$validOn) { - return $result; - } - - /* @todo propper error handling */ - if(!$loggable){ - throw new \Exception('This enity is not loggable therefore no previus versions can be obtained'); - } - - // Lets turn valid on into a date - try{ - $date = strtotime($validOn); - $date = date("Y-m-d H:i:s", $date); - - } catch (Exception $e) { - /* @todo thow propper exeption */ - throw new \Exception('Caught exception: ', $e->getMessage(), "\n"); - } - - // Lets try to get an version valid on that date - $queryBuilder= $this->em->getRepository('Gedmo\Loggable\Entity\LogEntry')->createQueryBuilder('l') - ->where('l.objectClass = :objectClass') - ->setParameter('objectClass', $this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()) - ->andWhere('l.objectId = :objectId') - ->setParameter('objectId', $result->getId()) - ->andWhere('l.loggedAt <= :loggedAt') - ->setParameter('loggedAt', $date) - ->setMaxResults(1) - ->orderBy('l.loggedAt', 'DESC'); - - $version = $queryBuilder->getQuery()->getOneOrNullResult(); - - /* @todo propper error handling */ - if(!$version){ - throw new \Exception('Could not find a valid version for date: '.$date); - } - - // Lets use the found version to rewind the object and return is - $repo = $this->em->getRepository('\Gedmo\Loggable\Entity\LogEntry'); // we use default log entry class - $repo->revert($result, $version->getVersion()); - - return $result; - } + private $params; + private $em; + private $serializer; + private $annotationReader; + + public function __construct(ParameterBagInterface $params, EntityManagerInterface $em, SerializerInterface $serializer, Reader $annotationReader) + { + $this->params = $params; + $this->em = $em; + $this->serializer = $serializer; + $this->annotationReader = $annotationReader; + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::VIEW => ['validOn', EventPriorities::PRE_SERIALIZE], + ]; + } + + public function validOn(GetResponseForControllerResultEvent $event) + { + $result = $event->getControllerResult(); + + // Lets get validOn from the query but deafult back to geldig op (for backward compatibality with api standaard) + $geldigOp = $event->getRequest()->query->get('geldigOp', false); + $validOn = $event->getRequest()->query->get('validOn', $geldigOp); + + // Only do somthing if fields is query supplied + if (!$validOn) { + return $result; + } + + // Lets see if this class has a Loggableannotation + $loggable = false; + $reflClass = new \ReflectionClass($result); + $annotations = $this->annotationReader->getClassAnnotations($reflClass); + + foreach ($annotations as $annotation) { + if (get_class($annotation) == "Gedmo\Mapping\Annotation\Loggable") { + $loggable = true; + } + } + /* @todo propper error handling */ + if (!$loggable) { + throw new \Exception('This enity is not loggable therefore no previus versions can be obtained'); + } + + // Lets turn valid on into a date + try { + $date = strtotime($validOn); + $date = date('Y-m-d H:i:s', $date); + } catch (Exception $e) { + /* @todo thow propper exeption */ + throw new \Exception('Caught exception: ', $e->getMessage(), "\n"); + } + + // Lets try to get an version valid on that date + $queryBuilder = $this->em->getRepository('Gedmo\Loggable\Entity\LogEntry')->createQueryBuilder('l') + ->where('l.objectClass = :objectClass') + ->setParameter('objectClass', $this->em->getMetadataFactory()->getMetadataFor(get_class($result))->getName()) + ->andWhere('l.objectId = :objectId') + ->setParameter('objectId', $result->getId()) + ->andWhere('l.loggedAt <= :loggedAt') + ->setParameter('loggedAt', $date) + ->setMaxResults(1) + ->orderBy('l.loggedAt', 'DESC'); + + $version = $queryBuilder->getQuery()->getOneOrNullResult(); + + /* @todo propper error handling */ + if (!$version) { + throw new \Exception('Could not find a valid version for date: '.$date); + } + + // Lets use the found version to rewind the object and return is + $repo = $this->em->getRepository('\Gedmo\Loggable\Entity\LogEntry'); // we use default log entry class + $repo->revert($result, $version->getVersion()); + + return $result; + } } diff --git a/api/src/Swagger/SwaggerDecorator.php b/api/src/Swagger/SwaggerDecorator.php index f0c871be..b0610232 100644 --- a/api/src/Swagger/SwaggerDecorator.php +++ b/api/src/Swagger/SwaggerDecorator.php @@ -1,182 +1,491 @@ decorated = $decorated; - $this->params = $params; - $this->cash = $cache; - } - - public function normalize($object, $format = null, array $context = []) - { - $docs = $this->decorated->normalize($object, $format, $context); - - // Lest add an host - if($this->params->get('common_ground.oas.host')){ - $docs['host']= $this->params->get('common_ground.oas.host'); - } - - // Lets set the servers - if(array_key_exists ('servers',$docs)){$docs['servers']=[];} - foreach($this->params->get('common_ground.oas.servers') as $key => $value){ - $docs['servers'][$key] = $value; - - } - - // Lets set the external documentation - if(array_key_exists ('externalDocs',$docs)){$docs['externalDocs']=[];} - foreach($this->params->get('common_ground.oas.externalDocs') as $key => $value){ - $docs['externalDocs'][$key] = $value; - - } - - // Lets add the commonground codes - if(array_key_exists ('x-commonground',$docs)){$docs['x-commonground']=[];} - - // Lets set the component type - $docs['x-commonground']['type'] = $this->params->get('common_ground.oas.type'); - - // Lets set the devolopers - if(array_key_exists ('developers',$docs['x-commonground'])){$docs['developers']=[];} - foreach($this->params->get('common_ground.oas.developers') as $key => $value){ - $docs['x-commonground']['developers'][$key] = $value; - - } - - // Lets set the build checks - if(array_key_exists ('builds',$docs['x-commonground'])){$docs['builds']=[];} - foreach($this->params->get('common_ground.oas.builds') as $key => $value){ - $docs['x-commonground']['builds'][$key] = $value; - } - - /*todo a loop within a lopo is butt ugly */ - foreach($docs['paths'] as $path => $calls){ - - foreach($calls as $method => $call){ - - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'Authorization', - 'description' => 'The JWT of the entity performing the request', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'API-Version', - 'description' => 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)', - 'example'=>'1.0.1', - 'in' => 'header', - ]; - /* - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Application-Id', - 'description' => 'The id of the application performing the request', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Subject-Identifier', - 'description' => 'An subject identifier for purpose registration (doelbinding)', - 'in' => 'header', - ]; - */ - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Logrecord-ID', - 'description' => 'A globally unique id of the request, which makes a request traceable throughout the network.', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Process-Id', - 'description' => 'A process id for purpose registration (doelbinding)', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Data-Elements', - 'description' => 'A list of requested data elements', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-NLX-Request-Data-Subject', - 'description' => 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`', - 'in' => 'header', - ]; - // NLX loging headers - $call['parameters'][] = [ - 'name' => 'X-Audit-Clarification', - 'description' => 'A clarification as to why a request has been made (doelbinding)', - 'in' => 'header', - ]; - - - if($method == "get"){ - // Lets add the extend functionality - $call['parameters'][] = [ - 'name' => 'extend[]', - 'required' => false, - 'description' => 'An array of nested objects to include in the return object', - 'in' => 'query', - 'schema'=>['type'=>'array'] - ]; - // Lets add the fields functionality - $call['parameters'][] = [ - 'name' => 'fields[]', - 'required' => false, - 'description' => 'An array of fields to return in output, wil return all fields is not supplied', - 'in' => 'query', - 'schema'=>['type'=>'array'] - ]; - // Lets add some time travel - $call['parameters'][] = [ - 'name' => 'validOn', - 'required' => false, - 'description' => 'Returns object as valid on a given date time', - 'schema'=>['type'=>'string', 'format' => 'date-time'], - 'in' => 'query', - ]; - $call['parameters'][] = [ - 'name' => 'validFrom', - 'required' => false, - 'description' => 'Returns objects valid from a given date time', - 'schema'=>['type'=>'string', 'format' => 'date-time'], - 'in' => 'query', - ]; - $call['parameters'][] = [ - 'name' => 'validUntil', - 'required' => false, - 'description' => 'Returns objects valid until a given date time', - 'schema'=>['type'=>'string', 'format' => 'date-time'], - 'in' => 'query', - ]; - } - - } - - - - } - return $docs; - } - - public function supportsNormalization($data, $format = null) - { - return $this->decorated->supportsNormalization($data, $format); - } -} \ No newline at end of file + private $metadataFactory; + private $documentationNormalizer; + private $decorated; + private $params; + private $cash; + private $em; + private $annotationReader; + private $camelCaseToSnakeCaseNameConverter; + + public function __construct( + NormalizerInterface $decorated, + ParameterBagInterface $params, + CacheInterface $cache, + EntityManagerInterface $em, + AnnotationReader $annotationReader, + CamelCaseToSnakeCaseNameConverter $camelCaseToSnakeCaseNameConverter + ) { + $this->decorated = $decorated; + $this->params = $params; + $this->cash = $cache; + $this->em = $em; + $this->annotationReader = $annotationReader; + $this->camelCaseToSnakeCaseNameConverter = $camelCaseToSnakeCaseNameConverter; + } + + public function normalize($object, $format = null, array $context = []) + { + $docs = $this->decorated->normalize($object, $format, $context); + + /* The we need to enrich al the entities and add the autoated routes */ + + //var_dump($docs); + + // Lets make sure that we have definitions + if (!array_key_exists('definitions', $docs)) { + $docs['definitions'] = []; + } + + // Lets make sure that we have tags + if (!array_key_exists('tags', $docs)) { + $docs['tags'] = []; + } + + // Lets make sure that we have security and JWT-Claims + if (!array_key_exists('securityDefinitions', $docs)) { + $docs['securityDefinitions'] = []; + } + + // Lets add JWT-Oauth + $docs['securityDefinitions']['JWT-Oauth'] = [ + 'type' => 'oauth2', + 'authorizationUrl'=> 'http://petstore.swagger.io/api/oauth/dialog', + 'flow' => 'implicit', + 'scopes' => [], //scopes will be filled later autmaticly + ]; + + $docs['securityDefinitions']['JWT-Token'] = [ + 'type' => 'apiKey', + 'in' => 'header', // can be "header", "query" or "cookie" + 'name' => 'Authorization', // name of the header, query parameter or cookie + 'scopes'=> [], //scopes will be filled later autmaticly + ]; + + // Lets get al the entities known to doctrine + $entities = $this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames(); + + $additionalDocs = []; + + // Then we loop trough the entities to find the api platform entities + foreach ($entities as $entity) { + //$reflector = new \ReflectionClass($entity); + $metadata = $this->em->getClassMetadata($entity); + $reflector = $metadata->getReflectionClass(); + + $properties = $metadata->getReflectionProperties(); + $annotations = $this->annotationReader->getClassAnnotations($reflector); + + foreach ($annotations as $annotation) { + $annotationReflector = new \ReflectionClass($annotation); + if ($annotationReflector->name == "ApiPlatform\Core\Annotation\ApiResource") { + + // Lets add the class info to the tag + $shortName = $reflector->getShortName(); + + $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); + $docblock = $factory->create($reflector->getDocComment()); + $summary = $docblock->getSummary(); + $description = $docblock->getDescription()->render(); + $description = $summary."\n\n".$description; + + $tag = []; + $tag['name'] = $shortName; + $tag['description'] = $description; + + $docs['tags'][] = $tag; + + // And lets add the aditional docs + + //$additionalEntityDocs = $this->getAdditionalEntityDocs($entity); + $entityDocs = $this->getAdditionalEntityDocs($entity); + // Only run if we have aditional docs + if(array_key_exists('properties',$entityDocs)){ + $additionalDocs = array_merge($additionalDocs, $entityDocs['properties']); + } + + // Security + $docs['securityDefinitions']['JWT-Oauth']['scopes'] = array_merge($docs['securityDefinitions']['JWT-Oauth']['scopes'], $entityDocs['security']); + $docs['securityDefinitions']['JWT-Token']['scopes'] = array_merge($docs['securityDefinitions']['JWT-Token']['scopes'], $entityDocs['security']); + + break; + } + } + } + + // Oke dit is echt but lelijk + $schemas = (array) $docs['definitions']; + foreach ($schemas as $schemaName => $schema) { + + // We can only merge if we actually have content + if (!in_array($schemaName, $additionalDocs)) { + continue; + } + + $additionalDocs[$schemaName] = array_merge((array) $schema, $additionalDocs[$schemaName]); + + $properties = (array) $schema['properties']; + foreach ($properties as $propertyName => $property) { + $additionalDocs[$schemaName]['properties'][$propertyName] = array_merge((array) $property, $additionalDocs[$schemaName]['properties'][$propertyName]); + } + } + $docs['definitions'] = $additionalDocs; + + // Lest add an host + if ($this->params->get('common_ground.oas.host')) { + $docs['host'] = $this->params->get('common_ground.oas.host'); + } + + // Lets set the servers + if (array_key_exists('servers', $docs)) { + $docs['servers'] = []; + } + foreach ($this->params->get('common_ground.oas.servers') as $key => $value) { + $docs['servers'][$key] = $value; + } + + // Lets set the external documentation + if (array_key_exists('externalDocs', $docs)) { + $docs['externalDocs'] = []; + } + foreach ($this->params->get('common_ground.oas.externalDocs') as $key => $value) { + $docs['externalDocs'][$key] = $value; + } + + // Lets add the commonground codes + if (array_key_exists('x-commonground', $docs)) { + $docs['x-commonground'] = []; + } + + // Lets set the component type + $docs['x-commonground']['type'] = $this->params->get('common_ground.oas.type'); + + // Lets set the devolopers + if (array_key_exists('developers', $docs['x-commonground'])) { + $docs['developers'] = []; + } + foreach ($this->params->get('common_ground.oas.developers') as $key => $value) { + $docs['x-commonground']['developers'][$key] = $value; + } + + // Lets set the build checks + if (array_key_exists('builds', $docs['x-commonground'])) { + $docs['builds'] = []; + } + foreach ($this->params->get('common_ground.oas.builds') as $key => $value) { + $docs['x-commonground']['builds'][$key] = $value; + } + + /*todo a loop within a lopo is butt ugly */ + foreach ($docs['paths'] as $path => $calls) { + foreach ($calls as $method => $call) { + + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'Authorization', + 'description' => 'The JWT of the entity performing the request', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'API-Version', + 'description' => 'The version of the API conform [Landelijke API-strategie.](https://geonovum.github.io/KP-APIs/#versioning)', + 'example' => '1.0.1', + 'in' => 'header', + ]; + /* + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Application-Id', + 'description' => 'The id of the application performing the request', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Subject-Identifier', + 'description' => 'An subject identifier for purpose registration (doelbinding)', + 'in' => 'header', + ]; + */ + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Logrecord-ID', + 'description' => 'A globally unique id of the request, which makes a request traceable throughout the network.', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Process-Id', + 'description' => 'A process id for purpose registration (doelbinding)', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Data-Elements', + 'description' => 'A list of requested data elements', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Request-Data-Subject', + 'description' => 'A key-value list of data subjects related to this request. e.g. `bsn=12345678, kenteken=ab-12-fg`', + 'in' => 'header', + ]; + // NLX loging headers + $call['parameters'][] = [ + 'name' => 'X-NLX-Audit-Clarification', + 'description' => 'A clarification as to why a request has been made (doelbinding)', + 'in' => 'header', + ]; + + if ($method == 'get') { + + // Health JSON + $call['produces'][] = 'application/health+json'; + + // WEBSUB header + $call['parameters'][] = [ + 'name' => 'Link', + 'description' => 'A [websub](https://www.w3.org/TR/websub/#discovery) header like ; rel="hub"', + 'in' => 'header', + ]; + + // Lets add the extend functionality + $call['parameters'][] = [ + 'name' => 'extend[]', + 'required' => false, + 'description' => 'An array of nested objects to include in the return object', + 'in' => 'query', + 'schema' => ['type'=>'array'], + ]; + // Lets add the fields functionality + $call['parameters'][] = [ + 'name' => 'fields[]', + 'required' => false, + 'description' => 'An array of fields to return in output, wil return all fields is not supplied', + 'in' => 'query', + 'schema' => ['type'=>'array'], + ]; + // Lets add some time travel + $call['parameters'][] = [ + 'name' => 'validOn', + 'required' => false, + 'description' => 'Returns object as valid on a given date time', + 'schema' => ['type'=>'string', 'format' => 'date-time'], + 'in' => 'query', + ]; + $call['parameters'][] = [ + 'name' => 'validFrom', + 'required' => false, + 'description' => 'Returns objects valid from a given date time', + 'schema' => ['type'=>'string', 'format' => 'date-time'], + 'in' => 'query', + ]; + $call['parameters'][] = [ + 'name' => 'validUntil', + 'required' => false, + 'description' => 'Returns objects valid until a given date time', + 'schema' => ['type'=>'string', 'format' => 'date-time'], + 'in' => 'query', + ]; + } + } + } + + /* @todo dit afbouwen */ + + /* + if(config heltchecks is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + + } + + if(config audittrail is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + + } + + if(config notifications is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + + } + + if(config authorization is true){ + $tag=[]; + $tag['name']=''; + $tag['description']=''; + array_unshift($fruits_list, $tag); + } + */ + //var_dump($docs); + + // Aditional tags + + // Security tag + if (getenv('HEALTH_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Health Checks'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + // Security tag + if (getenv('NOTIFICATION_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Notifications'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + // Security tag + if (getenv('AUDITTRAIL_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Audit trail'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + // Security tag + if (getenv('AUTH_ENABLED') == 'true') { + $tag = []; + $tag['name'] = 'Authorization'; + $tag['description'] = 'Authorization'; + $tag['externalDocs'] = []; + $tag['externalDocs'][] = ['url'=>'http://docs.my-api.com/pet-operations.htm']; + array_unshift($docs['tags'], $tag); + } + + //var_dump($docs); + return $docs; + } + + public function supportsNormalization($data, $format = null) + { + return $this->decorated->supportsNormalization($data, $format); + } + + private function getAdditionalEntityDocs($entity) + { + $metadata = $this->em->getClassMetadata($entity); + $reflector = $metadata->getReflectionClass(); + $properties = $metadata->getReflectionProperties(); + $annotations = $this->annotationReader->getClassAnnotations($reflector); + $additionalDocs = ['properties', 'security'=>[]]; + $required = []; + + // Add audittrail + // Add healthcheck + + $class = $reflector->getShortName(); + $path = '/'.$this->camelCaseToSnakeCaseNameConverter->normalize($class); + + // Lets take a look at the properties an annotions, + foreach ($properties as $property) { + + // The dockBlocks for thie property + $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); + $docblock = $factory->create($property->getDocComment()); + $tags = $docblock->getTags(); + $atributes = []; + $groups = []; + + foreach ($tags as $tag) { + $name = $tag->getName(); + $description = $tag->getDescription(); + // + //$description = (string) $description; + + switch ($name) { + // Docblocks + case 'example': + $atributes['example'] = (string) $description; + break; + + // Groups + case 'Groups': + $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Serializer\Annotation\Groups"); + $groups = $propertyAnnotation->getGroups(); + break; + + // Constrainds (Validation) + case "Assert\Uuid": + $atributes['format'] = 'uuid'; + break; + case "Assert\Email": + $atributes['format'] = 'email'; + break; + case "Assert\Url": + $atributes['format'] = 'url'; + break; + case "Assert\Regex": + $atributes['format'] = 'regex'; + break; + case "Assert\Ip": + $atributes['format'] = 'ip'; + break; + case "Assert\Json": + $atributes['format'] = 'json'; + break; + case "Assert\Choice": + //@todo + //$atributes['format'] = 'json'; + break; + + case "Assert\NotNull": + $required[] = $property->name; + break; + case "Assert\Length": + $propertyAnnotation = $this->annotationReader->getPropertyAnnotation($property, "Symfony\Component\Validator\Constraints\Length"); + if ($propertyAnnotation->max) { + $atributes['maxLength'] = $propertyAnnotation->max; + } + if ($propertyAnnotation->min) { + $atributes['minLength'] = $propertyAnnotation->min; + } + break; + } + } + // Lets write everything to the docs + foreach ($groups as $group) { + //$additionalDocs["components"]['schemas'][$class."-".$group] = $atributes; + $additionalDocs['properties'][$class.'-'.$group]['properties'][$property->name] = $atributes; + $additionalDocs['properties'][$class.'-'.$group]['required'] = $required; + + if (!array_key_exists($group, $additionalDocs['security'])) { + $additionalDocs['security'][$group] = $group.' right to the '.$class.' resource'; + } + } + } + + return $additionalDocs; + } +} diff --git a/api/src/Types/IncompleteDateType.php b/api/src/Types/IncompleteDateType.php index 8badbc8e..88f66c3c 100644 --- a/api/src/Types/IncompleteDateType.php +++ b/api/src/Types/IncompleteDateType.php @@ -2,54 +2,58 @@ namespace App\Types; -use Doctrine\DBAL\Types\Type; -use Doctrine\DBAL\Platforms\AbstractPlatform; - use App\ValueObject\IncompleteDate; +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Type; class IncompleteDateType extends Type { - const INCOMPLETEDATE = 'incompleteDate'; - - public function getName() - { - return self::INCOMPLETEDATE; - } - - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) - { - return 'INTEGER'; - } - - public function convertToPHPValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them - list($year, $month, $day) = sscanf($value, '%04u%02u%02u'); - - return new IncompleteDate($year, $month, $day); - } - - public function convertToDatabaseValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them - if ($value instanceof IncompleteDate) { - $value = sprintf('%04u%02u%02u', $value->getYear(), $value->getMonth(), $value->getDay()); - } - else{ - if(!array_key_exists("year",$value)){ $value['year']=0;} - if(!array_key_exists("month",$value)){ $value['month']=0;} - if(!array_key_exists("day",$value)){ $value['day']=0;} - $value = sprintf('%04u%02u%02u', (int) $value['year'], (int) $value['month'], (int) $value['day']); - } - - return $value; - } -} \ No newline at end of file + const INCOMPLETEDATE = 'incompleteDate'; + + public function getName() + { + return self::INCOMPLETEDATE; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return 'INTEGER'; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them + list($year, $month, $day) = sscanf($value, '%04u%02u%02u'); + + return new IncompleteDate($year, $month, $day); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + // We save incomplete date's as YYYYMMDD integer values so that we can easily index and order on them + if ($value instanceof IncompleteDate) { + $value = sprintf('%04u%02u%02u', $value->getYear(), $value->getMonth(), $value->getDay()); + } else { + if (!array_key_exists('year', $value)) { + $value['year'] = 0; + } + if (!array_key_exists('month', $value)) { + $value['month'] = 0; + } + if (!array_key_exists('day', $value)) { + $value['day'] = 0; + } + $value = sprintf('%04u%02u%02u', (int) $value['year'], (int) $value['month'], (int) $value['day']); + } + + return $value; + } +} diff --git a/api/src/Types/UnderInvestigationType.php b/api/src/Types/UnderInvestigationType.php index e66e7e7c..4717bf51 100644 --- a/api/src/Types/UnderInvestigationType.php +++ b/api/src/Types/UnderInvestigationType.php @@ -2,66 +2,69 @@ namespace App\Types; -use Doctrine\DBAL\Types\Type; -use Doctrine\DBAL\Platforms\AbstractPlatform; - use App\ValueObject\UnderInvestigation; +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Type; class UnderInvestigationType extends Type { - const UNDERINVESTIGATION = 'underInvestigation'; - - public function getName() - { - return self::UNDERINVESTIGATION; - } - - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) - { - return 'JSON'; - } - - public function convertToPHPValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - //list($longitude, $latitude) = sscanf($value, 'JSON(%s)'); - $value= json_decode ($value, true); - //var_dump($data); - $date = $value['date']; - $properties = $value['properties']; - return new UnderInvestigation($properties, $date); - } - - public function convertToDatabaseValue($value, AbstractPlatform $platform) - { - // Lets make this nullable - if(!$value){ - return null; - } - if ($value instanceof UnderInvestigation) { - /* @todo throw an error ir the property isn't a boolean*/ - $value= ["properties"=> $value->getProperties(),"date"=> $value->getDate()]; - $value = json_encode($value); - } - else{ - // lets make sure we have a properties array - if(!array_key_exists("properties",$value)){ $value['properties']=[];} - // Lets analyse this dataset - foreach ($value as $key => $property){ - // lets skip the date and propertieskeys - if($key=='date' || $key=='properties'){continue;} - /* @todo throw an error ir the property isn't a boolean*/ - - // lets add the property to the stack - $value['properties'][$key] = $property; - unset($value[$key]); - } - $value = json_encode($value); - } - - return $value; - } -} \ No newline at end of file + const UNDERINVESTIGATION = 'underInvestigation'; + + public function getName() + { + return self::UNDERINVESTIGATION; + } + + public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + { + return 'JSON'; + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + //list($longitude, $latitude) = sscanf($value, 'JSON(%s)'); + $value = json_decode($value, true); + //var_dump($data); + $date = $value['date']; + $properties = $value['properties']; + + return new UnderInvestigation($properties, $date); + } + + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + // Lets make this nullable + if (!$value) { + return; + } + if ($value instanceof UnderInvestigation) { + /* @todo throw an error ir the property isn't a boolean*/ + $value = ['properties'=> $value->getProperties(), 'date'=> $value->getDate()]; + $value = json_encode($value); + } else { + // lets make sure we have a properties array + if (!array_key_exists('properties', $value)) { + $value['properties'] = []; + } + // Lets analyse this dataset + foreach ($value as $key => $property) { + // lets skip the date and propertieskeys + if ($key == 'date' || $key == 'properties') { + continue; + } + /* @todo throw an error ir the property isn't a boolean*/ + + // lets add the property to the stack + $value['properties'][$key] = $property; + unset($value[$key]); + } + $value = json_encode($value); + } + + return $value; + } +} diff --git a/api/src/ValueObject/IncompleteDate.php b/api/src/ValueObject/IncompleteDate.php index 97149fc6..c9fbb072 100644 --- a/api/src/ValueObject/IncompleteDate.php +++ b/api/src/ValueObject/IncompleteDate.php @@ -2,64 +2,72 @@ namespace App\ValueObject; - /* * Incomplomplete data class - * + * * This doctrine value object is designd to work in tendem with the incompleteData mapping type to provide doctrine support for the working with incomplete date objects - * - * + * + * */ -class IncompleteDate +class IncompleteDate { - /** - * @param integer $day - * @param integer $month - * @param integer $year - */ - public function __construct($year, $month, $day) - { - $this->day = $day; - $this->month= $month; - $this->year = $year; - } - - /** - * @return integer - */ - public function getDay() - { - // If the day is missing we return zero - if(!$this->day){return 0;} - return $this->day; - } - - /** - * @return integer - */ - public function getMonth() - { - // If the month is missing we return zero - if(!$this->month){return 0;} - return $this->month; - } - - /** - * @return integer - */ - public function getYear() - { - // If the year is missing we return zero - if(!$this->year){return 0;} - return $this->year; - } - - /** - * @return string - */ - public function getDate() - { - return sprintf('%04u-%02u-%02u', $this->getYear(), $this->getMonth(), $this->getDay()); - } -} \ No newline at end of file + /** + * @param int $day + * @param int $month + * @param int $year + */ + public function __construct($year, $month, $day) + { + $this->day = $day; + $this->month = $month; + $this->year = $year; + } + + /** + * @return int + */ + public function getDay() + { + // If the day is missing we return zero + if (!$this->day) { + return 0; + } + + return $this->day; + } + + /** + * @return int + */ + public function getMonth() + { + // If the month is missing we return zero + if (!$this->month) { + return 0; + } + + return $this->month; + } + + /** + * @return int + */ + public function getYear() + { + // If the year is missing we return zero + if (!$this->year) { + return 0; + } + + return $this->year; + } + + /** + * @return string + */ + public function getDate() + { + return sprintf('%04u-%02u-%02u', $this->getYear(), $this->getMonth(), $this->getDay()); + } +} diff --git a/api/src/ValueObject/UnderInvestigation.php b/api/src/ValueObject/UnderInvestigation.php index 63912361..bbbb98f1 100644 --- a/api/src/ValueObject/UnderInvestigation.php +++ b/api/src/ValueObject/UnderInvestigation.php @@ -2,32 +2,31 @@ namespace App\ValueObject; - -class UnderInvestigation +class UnderInvestigation { - /** - * @param array $properties - * @param string $date - */ - public function __construct($properties, $date) - { - $this->properties= $properties; - $this->date= $date; - } - - /** - * @return array - */ - public function getProperties() - { - return $this->properties; - } - - /** - * @return string - */ - public function getDate() - { - return $this->date; - } -} \ No newline at end of file + /** + * @param array $properties + * @param string $date + */ + public function __construct($properties, $date) + { + $this->properties = $properties; + $this->date = $date; + } + + /** + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * @return string + */ + public function getDate() + { + return $this->date; + } +} diff --git a/api/symfony.lock b/api/symfony.lock index be591f61..e97be40b 100644 --- a/api/symfony.lock +++ b/api/symfony.lock @@ -73,9 +73,6 @@ "src/Repository/.gitignore" ] }, - "doctrine/doctrine-cache-bundle": { - "version": "1.3.5" - }, "doctrine/doctrine-fixtures-bundle": { "version": "3.0", "recipe": { @@ -109,6 +106,9 @@ "doctrine/reflection": { "version": "v1.0.0" }, + "doctrine/rst-parser": { + "version": "0.1.0" + }, "easyrdf/easyrdf": { "version": "0.9.1" }, @@ -142,6 +142,9 @@ "jdorn/sql-formatter": { "version": "v1.2.17" }, + "knplabs/knp-markdown-bundle": { + "version": "1.8.1" + }, "lcobucci/jwt": { "version": "3.3.1" }, @@ -160,6 +163,9 @@ "config/packages/lexik_jwt_authentication.yaml" ] }, + "michelf/php-markdown": { + "version": "1.9.0" + }, "moneyphp/money": { "version": "v1.3.0" }, @@ -181,6 +187,9 @@ "nikic/php-parser": { "version": "v4.2.2" }, + "php": { + "version": "7.3" + }, "php-cs-fixer/diff": { "version": "v1.3.0" }, @@ -226,6 +235,18 @@ "config/packages/ramsey_uuid_doctrine.yaml" ] }, + "sensio/framework-extra-bundle": { + "version": "5.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "5.2", + "ref": "fb7e19da7f013d0d422fa9bce16f5c510e27609b" + }, + "files": [ + "config/packages/sensio_framework_extra.yaml" + ] + }, "sensiolabs/security-checker": { "version": "4.0", "recipe": { @@ -293,6 +314,9 @@ "symfony/dotenv": { "version": "v4.3.1" }, + "symfony/error-handler": { + "version": "v4.4.1" + }, "symfony/event-dispatcher": { "version": "v4.3.1" }, diff --git a/api/templates/helm/Chart.yaml.twig b/api/templates/helm/Chart.yaml.twig index 7795e920..38f81166 100644 --- a/api/templates/helm/Chart.yaml.twig +++ b/api/templates/helm/Chart.yaml.twig @@ -1,7 +1,7 @@ apiVersion: v1 -appVersion: {{ container_project_version }} -description: {{ app_description }} -name: {{ container_project_title|replace({' ': ''})|lower }} +appVersion: {{ app_version }} +description: '{{ app_description }}' +name: {{ app_name|replace({' ': ''})|lower }} version: 0.1.0 -home: https://common-ground.dev -icon: https://common-ground.dev/logo-250x250.png \ No newline at end of file +home: {{ app_home }} +icon: {{ app_logo }} \ No newline at end of file diff --git a/api/templates/helm/values.yaml.twig b/api/templates/helm/Values.yaml.twig similarity index 75% rename from api/templates/helm/values.yaml.twig rename to api/templates/helm/Values.yaml.twig index 1d024ae9..10375e26 100644 --- a/api/templates/helm/values.yaml.twig +++ b/api/templates/helm/Values.yaml.twig @@ -5,23 +5,46 @@ settings: registryBase: {{ container_registry_base }} projectName: {{ container_project_name }} + name: {{ app_name }} + title: {{ app_title }} + version: {{ app_version }} + description: '{{ app_description }}' + repro: '{{ app_repro }}' + subdomain: {{ app_subdomain }} + domains: +{% for domain in app_domains %} + - {{ domain }} +{% endfor %} + domainsJson: {{ app_domains | json_encode()|raw }} + organisationName: {{ organization_name }} + email: {{ organization_email }} + country: {{ organization_country }} + state: {{ organization_state }} + locality: {{ organization_locality }} + unit: {{ organization_unit }} + demo: {{ app_demo }} env: {{ app_env }} debug: {{ app_debug }} replicaCount: 1 corsAllowOrigin: ['*'] - trustedHosts: '^(.+\.)?common-ground\.dev$|^(.+\.)?zaakonline\.nl$|^(.+\.)?conduction\.nl$|^example\.com$|^(.+\.)?178.128.142.152$|178.128.142.152|localhost' + trustedHosts: '{{ trusted_hosts }}' pullPolicy: Always # You will need these proxies on kubernetes trustedProxies: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 - # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer loadbalancerEnabled: false # If you want to enable NLX you are requered to add the appropreate certificates to you nlx-settings folder (located in the /api folder) nlxInwayEnabled: {{ nlx_inway }} - nlxOutwayEnabled: {{ nlx_outway }} - + # If you are runnig a single component on a kubernetes cluster you can just easaliy enable the load balancer, if not you need to set up a multi component load balancer + notificationEnabled: false + audittrailEnabled: false + authorisationEnabled: false + healthEnabled: false + archiveEnabled: false + php: repository: docker.io/conduction/protocomponent-php diff --git a/api/templates/publiccode/publiccode.yaml.twig b/api/templates/publiccode/publiccode.yaml.twig new file mode 100644 index 00000000..0d9dc439 --- /dev/null +++ b/api/templates/publiccode/publiccode.yaml.twig @@ -0,0 +1,118 @@ +{# Read https://docs.italia.it/italia/developers-italia/publiccodeyml-en/en/master/schema.core.html for the complete standard#} +publiccodeYmlVersion: "0.2" + +name: {{ app_name }} +applicationSuite: commonground +url: "{{ app_repro }}" +landingURL: "{{ app_demo }}" +{# we asume that everything is based on the proto component #} +isBasedOn: "https://github.com/ConductionNL/Proto-component-commonground.git" +softwareVersion: "{{ app_version }}" +releaseDate: "{{ "now"|date("Y-d-m") }}" +logo: {{ app_logo }} +monochromeLogo: img/logo-mono.svg + +inputTypes: + - application/json + - application/xml + +outputTypes: + - application/json + - application/ld+json + - application/hal+json + - application/vnd.api+json + - application/health+json + - application/xml + - application/x-yaml + - text/csv + - text/html + +platforms: + - web + +categories: + - it-development + +usedBy: + - Gemeente Utrecht + - Gemeente Den Haag + - Gemeente Hoorn + + +roadmap: "{{ app_repro }}/blob/master/ROADMAP.md" + +developmentStatus: development + +softwareType: "standalone/other" + +#intendedAudience: +# scope: +# - science-and-technology +# countries: +# - it +# - de +# unsupportedCountries: +# - us + +description: + en: +# localisedName: Medusa +# genericName: Text Editor +# shortDescription: > +# This description can have a maximum 150 +# characters long. We should not fill the +# remaining space with "Lorem Ipsum". End +# +# longDescription: > +# Very long description of this software, also split +# on multiple rows. You should note what the software +# is and why one should need it. + + documentation: "{{ app_repro }}/blob/master/README.md" + apiDocumentation: "{{ app_demo }}" +# +# features: +# - Very important feature +# - Will run without a problem +# - Has zero bugs +# - Solves all the problems of the world +# screenshots: +# - img/sshot1.jpg +# - img/sshot2.jpg +# - img/sshot3.jpg +# videos: +# - https://youtube.com/xxxxxxxx +# awards: +# - 1st Price Software of the year + +legal: + license: EUPL-1.2 + mainCopyrightOwner: Conduction + repoOwner: Conduction + authorsFile: AUTHORS.md + +maintenance: + type: "internal" + + contractors: + - name: "Conduction B.V" + email: "info@conduction.nl" + website: "https://www.conduction.nl" + until: "2099-01-01" + + contacts: + - name: Ruben van der Linde + email: "ruben@conduction.nl" + affiliation: "Conduction B.V" + +localisation: + localisationReady: yes + availableLanguages: + - en + - nl + +dependsOn: + open: + - name: Kubernetes + versionMin: "1.15.5-do.1" + diff --git a/docker-compose.yml b/docker-compose.yml index 0663610f..c6f6b218 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,6 @@ x-cache: - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-varnish - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-admin - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-client - - ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-h2-proxy services: php: @@ -27,18 +26,38 @@ services: # If you develop on Linux, uncomment the following line to use a bind-mounted host directory instead # - ./api/var:/srv/api/var:rw environment: + - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} + - CONTAINER_PROJECT_NAME=${CONTAINER_PROJECT_NAME} + - CONTAINER_REPRO=${CONTAINER_REPRO} + #- DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 + - DATABASE_URL=mysql://api-platform:!ChangeMe!@db/api?serverVersion=10.1 - APP_ENV=${APP_ENV} - APP_DEBUG=${APP_DEBUG} - - APP_VERSION=${CONTAINER_PROJECT_VERSION} - - APP_TITLE=${CONTAINER_PROJECT_TITLE} - - APP_NAME=${CONTAINER_PROJECT_NAME} + - APP_VERSION=${APP_VERSION} + - APP_NAME=${APP_NAME} + - APP_TITLE=${APP_TITLE} + - APP_SUBDOMAIN=${APP_SUBDOMAIN} + - APP_DOMAINS=${APP_DOMAINS} + - APP_DEMO=${APP_DEMO} + - APP_REPRO=${APP_REPRO} + - APP_DESCRIPTION=${APP_DESCRIPTION} + - APP_LOGO=${APP_LOGO} + - APP_HOME=${APP_HOME} + - ORGANIZATION_NAME=${ORGANIZATION_NAME} + - ORGANIZATION_EMAIL_ADDRESS=${ORGANIZATION_EMAIL_ADDRESS} + - ORGANIZATION_COUNTRY_NAME=${ORGANIZATION_COUNTRY_NAME} + - ORGANIZATION_STATE=${ORGANIZATION_STATE} + - ORGANIZATION_LOCALITY=${ORGANIZATION_LOCALITY} + - ORGANIZATION_UNIT_NAME=${ORGANIZATION_UNIT_NAME} + - TRUSTED_PROXIES=${TRUSTED_PROXIES} + - TRUSTED_HOSTS=${TRUSTED_HOSTS} + - AUTH_ENABLED=${AUTH_ENABLED} + - AUDITTRAIL_ENABLED=${AUDITTRAIL_ENABLED} + - NOTIFICATION_ENABLED=${NOTIFICATION_ENABLED} + - HEALTH_ENABLED=${HEALTH_ENABLED} + - ARCHIVE_ENABLED=${ARCHIVE_ENABLED} - NLX_OUTWAY=${NLX_OUTWAY} - NLX_INWAY=${NLX_INWAY} - - CONTAINER_REGISTRY_BASE=${CONTAINER_REGISTRY_BASE} - - CONTAINER_PROJECT_TITLE=${CONTAINER_PROJECT_TITLE} - - CONTAINER_PROJECT_NAME=${CONTAINER_PROJECT_NAME} - - CONTAINER_PROJECT_VERSION=${CONTAINER_PROJECT_VERSION} - - DATABASE_URL=postgres://api-platform:!ChangeMe!@db/api?serverVersion=10.1 ports: - "8082:80" @@ -79,7 +98,7 @@ services: ports: - "8081:80" environment: - - PHP_SERVICE=api + - BACKENDS=php nlx-outway: image: ${CONTAINER_REGISTRY_BASE}/${CONTAINER_PROJECT_NAME}-nlx-outway:${APP_ENV} @@ -150,15 +169,28 @@ services: networks: - nlx + #db: + # image: postgres:10-alpine + # environment: + # - POSTGRES_DB=api + # - POSTGRES_USER=api-platform + # You should definitely change the password in production + # - POSTGRES_PASSWORD=!ChangeMe! + # volumes: + # - db-data:/var/lib/postgresql/data:rw + db: - image: postgres:10-alpine + image: mysql:5.6 + restart: always environment: - - POSTGRES_DB=api - - POSTGRES_USER=api-platform - # You should definitely change the password in production - - POSTGRES_PASSWORD=!ChangeMe! + - MYSQL_ROOT_PASSWORD=example + - MYSQL_DATABASE=api + - MYSQL_USER=api-platform + - MYSQL_PASSWORD=!ChangeMe! volumes: - - db-data:/var/lib/postgresql/data:rw + - db-mysql:/var/lib/mysql:rw + ports: + - "3366:3306" mercure: # In production, you may want to use the managed version of Mercure, https://mercure.rocks @@ -233,4 +265,5 @@ networks: volumes: db-data: {} + db-mysql: {} nlx-data-2: {}