Initial commit
This commit is contained in:
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@@ -0,0 +1,14 @@
|
||||
# This is the top-most .editorconfig file; do not search in parent directories.
|
||||
root = true
|
||||
|
||||
# All files.
|
||||
[*]
|
||||
end_of_line = LF
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
.DS_Store
|
||||
.vscode
|
||||
/vendor
|
||||
composer.lock
|
||||
.phpunit.result.cache
|
||||
/var
|
||||
.php-cs-fixer.cache
|
||||
32
.php-cs-fixer.dist.php
Normal file
32
.php-cs-fixer.dist.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
|
||||
'binary_operator_spaces' => [
|
||||
'operators' => [
|
||||
'=' => 'align_single_space',
|
||||
'=>' => 'align_single_space',
|
||||
],
|
||||
],
|
||||
|
||||
'single_blank_line_at_eof' => true,
|
||||
'phpdoc_align' => false,
|
||||
'phpdoc_to_comment' => false,
|
||||
'strict_comparison' => true,
|
||||
'declare_strict_types' => true,
|
||||
'single_trait_insert_per_statement' => false,
|
||||
'nullable_type_declaration_for_default_null_value' => true,
|
||||
'increment_style' => [
|
||||
'style' => 'post',
|
||||
],
|
||||
])
|
||||
->setFinder(
|
||||
(new PhpCsFixer\Finder())
|
||||
->in(__DIR__)
|
||||
->exclude('var')
|
||||
)
|
||||
;
|
||||
6
Containerfile
Normal file
6
Containerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
FROM php:8.3-alpine
|
||||
|
||||
WORKDIR /code
|
||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||
COPY ./ /code
|
||||
|
||||
16
Makefile
Normal file
16
Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
PHP = docker compose run php
|
||||
|
||||
.PHONY: composer_install composer_update static_analysis tests
|
||||
|
||||
composer_install:
|
||||
@$(PHP) composer install
|
||||
|
||||
composer_update:
|
||||
@$(PHP) composer update
|
||||
|
||||
static_analysis:
|
||||
@$(PHP) vendor/bin/psalm
|
||||
|
||||
tests:
|
||||
@$(PHP) rm -rf var/cache
|
||||
@$(PHP) vendor/bin/phpunit
|
||||
119
README.md
Normal file
119
README.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Symfony Bundle Skeleton
|
||||
|
||||
A **WORK IN PROGRESS** skeleton for creating Symfony Bundles.
|
||||
|
||||
This skeleton is a very basic bundle with comments explaining what various bits are doing.
|
||||
|
||||
The bundle is called `PcmExampleBundle` and contains a `Greeting` class with a `greet(): string` method.
|
||||
|
||||
The `greet()` method returns a string welcoming someone who's name you can specify in the bundle configuration file.
|
||||
|
||||
|
||||
# Installing dependencies
|
||||
|
||||
You need to run `docker compose run php` before any composer commands. EG:
|
||||
```sh
|
||||
docker compose run php composer require symfony/twig-bundle
|
||||
```
|
||||
The Makefile has some common shorthands as usual.
|
||||
|
||||
|
||||
# Modifying this bundle
|
||||
|
||||
To change this bundle from `pcm/example-bundle` to something new there are few files you need to change.
|
||||
|
||||
1. **Bundle PHP file and namespace**
|
||||
|
||||
The file at `src/PcmExampleBundle.php` should have it's class name and filename changed.
|
||||
|
||||
If you are creating a bundle called `pcm/epic-login-bundle` the namespace should be `Pcm\EpicLogin`
|
||||
while the class name should be `PcmEpicLoginBundle`.
|
||||
|
||||
Subsequently, all namespaces should be changed to start with `pcm\epiclogin`.
|
||||
|
||||
2. **composer metadata**
|
||||
|
||||
Update the `name` and `description` fields of the `composer.json` file with appropriate names.
|
||||
The name should
|
||||
|
||||
You will also need to update the PSR autoload classes with your bundle's class name.
|
||||
|
||||
Optionally edit the authors if required.
|
||||
|
||||
3. **Config files**
|
||||
|
||||
- Chamge 'bundles.php` to use your new bundle class
|
||||
- Modify `services.yaml` when required
|
||||
- Update `definition.yaml` to specify your config structure (or remove if no config is required)
|
||||
|
||||
4. **Test files**
|
||||
|
||||
The `TestKernel` needs to return an array containing your bundle class.
|
||||
|
||||
Again, namespaces need changing to whatever is appropriate.
|
||||
|
||||
# PHPUnit testing
|
||||
|
||||
The bundle and it's configuration can be tested with PHPUnit.
|
||||
|
||||
This was a worthwhile section to add.
|
||||
|
||||
|
||||
# Installing a development version of the bundle
|
||||
|
||||
If you need to install the bundle to test stuff (EG to see how certain Twig templates look, etc) you can do so
|
||||
by using a development version of the bundle.
|
||||
|
||||
### Preparing the composer.json file
|
||||
|
||||
First, make sure your Symfony project has the following in it's `composer.json` file:
|
||||
```json
|
||||
{
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
}
|
||||
```
|
||||
|
||||
Next, you need to add the repository to the `composer.json` file, just as you would any other PCM bundle:
|
||||
```json
|
||||
{
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "ssh://example/bundle.git"
|
||||
},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Installing the development bundle
|
||||
|
||||
You can now install the bundle with composer. Because the bundle does not yet have a tagged version we
|
||||
have to specify that it's a dev bundle alongside a branch to use. For example:
|
||||
```sh
|
||||
composer require pcm/example-bundle:dev-develop
|
||||
```
|
||||
|
||||
The `dev-develop` part is specifying both that it's a **dev** package and that we want to use the **develop** branch. If you wanted to use the `master` branch you would specify as so: `dev-master`.
|
||||
|
||||
If a flex recipe is present it will prompt you to install it.
|
||||
|
||||
**NOTE** that the "symfony.lock" file will generate an incorrect version number "develop.9999999". This causes issues when uninstalling, so manually change this value to be `dev-develop` or whichever version you installed.
|
||||
|
||||
### Updating the development bundle
|
||||
|
||||
You can make changes to the bundle whilst it's installed. Once you've pushed your changes with git you can run a composer update to retrieve the most recent changes:
|
||||
```sh
|
||||
composer update pcm/example-bundle
|
||||
```
|
||||
|
||||
### Uninstalling your development bundle
|
||||
|
||||
Make sure that the bundle version is correct in the `symfony.lock` file (see above) before running the usual uninstall command:
|
||||
```sh
|
||||
composer remove pcm/example-bundle
|
||||
```
|
||||
|
||||
# Creating a flex recipe
|
||||
|
||||
See the flex recipe repo for info on how to do this.
|
||||
7
compose.yml
Normal file
7
compose.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
services:
|
||||
php:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Containerfile
|
||||
volumes:
|
||||
- ./:/code
|
||||
40
composer.json
Normal file
40
composer.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "pcm/example-bundle",
|
||||
"description": "PCM Example Bundle",
|
||||
"type": "symfony-bundle",
|
||||
"license": "MIT",
|
||||
"version": "dev-develop",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bradley Goode",
|
||||
"email": "bg@pcmsystems.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Matt Feeney",
|
||||
"email": "mf@pcmsystems.co.uk"
|
||||
}
|
||||
],
|
||||
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Pcm\\ExampleBundle\\": "src/"
|
||||
}
|
||||
},
|
||||
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Pcm\\ExampleBundle\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
|
||||
"require": {
|
||||
"symfony/dependency-injection": "^7.1",
|
||||
"symfony/framework-bundle": "^7.1",
|
||||
"symfony/yaml": "^7.1"
|
||||
},
|
||||
|
||||
"require-dev": {
|
||||
"symfony/test-pack": "^1.1",
|
||||
"friendsofphp/php-cs-fixer": "^3.61"
|
||||
}
|
||||
}
|
||||
12
config/bundles.php
Normal file
12
config/bundles.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Here we define the environments the bundle is allowed to be in.
|
||||
//
|
||||
// Most of the time we probably want to have access to our bundle
|
||||
// in all environments (prod, dev, test etc).
|
||||
return [
|
||||
Pcm\ExampleBundle\PcmExampleBundle::class => ['all' => true],
|
||||
];
|
||||
|
||||
16
config/definition.php
Normal file
16
config/definition.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
|
||||
|
||||
// This file is imported and used by the main bundle class to
|
||||
// define how the configuration should look.
|
||||
return static function (DefinitionConfigurator $definition): void {
|
||||
$definition->rootNode()
|
||||
->children()
|
||||
->scalarNode('name')->defaultValue('Mr. NoName')->cannotBeEmpty()->end()
|
||||
->end()
|
||||
;
|
||||
};
|
||||
|
||||
28
config/services.yaml
Normal file
28
config/services.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
# Hide the fully qualified Greeting class name from public view
|
||||
# but give the class an alias. This alias will be made public instead.
|
||||
#
|
||||
# Read the documentation to see why we do this:
|
||||
# https://symfony.com/doc/current/service_container/autowiring.html#service-autowiring-alias
|
||||
#
|
||||
Pcm\ExampleBundle\Greeting:
|
||||
public: false
|
||||
alias: pcm_example.greeting
|
||||
|
||||
|
||||
# Mark the alias we created as public.
|
||||
pcm_example.greeting:
|
||||
public: true
|
||||
class: Pcm\ExampleBundle\Greeting
|
||||
|
||||
|
||||
# If we were defining a twig extension, we'd want to add the twig.runtime tag
|
||||
# so it loads correctly.
|
||||
#
|
||||
# Pcm\ExampleBundle\SomeTwigRuntime
|
||||
# tags:
|
||||
# - { name: twig.runtime }
|
||||
19
phpunit.xml.dist
Normal file
19
phpunit.xml.dist
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="./vendor/autoload.php">
|
||||
<coverage>
|
||||
<include>
|
||||
<directory>./src</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1"/>
|
||||
<ini name="intl.default_locale" value="en"/>
|
||||
<ini name="intl.error_level" value="0"/>
|
||||
<ini name="memory_limit" value="-1"/>
|
||||
</php>
|
||||
<testsuites>
|
||||
<testsuite name="Test suite">
|
||||
<directory suffix="Test.php">./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
18
src/Greeting.php
Normal file
18
src/Greeting.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\ExampleBundle;
|
||||
|
||||
final class Greeting
|
||||
{
|
||||
public function __construct(private string $name)
|
||||
{
|
||||
}
|
||||
|
||||
public function greetPerson(): string
|
||||
{
|
||||
return sprintf("Hello there %s! Hope you're well.", $this->name);
|
||||
}
|
||||
}
|
||||
|
||||
44
src/PcmExampleBundle.php
Normal file
44
src/PcmExampleBundle.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\ExampleBundle;
|
||||
|
||||
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
|
||||
|
||||
final class PcmExampleBundle extends AbstractBundle
|
||||
{
|
||||
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
|
||||
{
|
||||
/**
|
||||
* Load the services defined in services.yaml into the container.
|
||||
*/
|
||||
$container->import('../config/services.yaml');
|
||||
|
||||
/**
|
||||
* The "$config" variable contains an array representing the
|
||||
* configuration and it's values.
|
||||
*
|
||||
* We can use it to configure the service container, for example
|
||||
* by passing in arguments to any services we have defined.
|
||||
*
|
||||
* (see services.yaml)
|
||||
*/
|
||||
$container->services()
|
||||
->get('pcm_example.greeting')
|
||||
->arg('$name', $config['name'])
|
||||
;
|
||||
}
|
||||
|
||||
public function configure(DefinitionConfigurator $definition): void
|
||||
{
|
||||
/**
|
||||
* Import the config definition (see definition.php)
|
||||
*/
|
||||
$definition->import('../config/definition.php');
|
||||
}
|
||||
}
|
||||
|
||||
45
tests/Config/ConfigurationTest.php
Normal file
45
tests/Config/ConfigurationTest.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\ExampleBundle\Tests\Config;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Configuration;
|
||||
use Symfony\Component\Config\Definition\Processor;
|
||||
|
||||
/**
|
||||
* Test to make sure the config validation is working as expected.
|
||||
*/
|
||||
class ConfigurationTest extends TestCase
|
||||
{
|
||||
private Configuration $configuration;
|
||||
private Processor $processor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->configuration = new Configuration(true);
|
||||
$this->processor = new Processor();
|
||||
}
|
||||
|
||||
public function testThrowsIfNameIsEmpty()
|
||||
{
|
||||
$config = $this->getValidConfig();
|
||||
$config['name'] = '';
|
||||
$this->expectException(\Exception::class);
|
||||
$this->validateConfig($config);
|
||||
}
|
||||
|
||||
private function validateConfig(array $config): array
|
||||
{
|
||||
return $this->processor->processConfiguration($this->configuration, [$config]);
|
||||
}
|
||||
|
||||
private function getValidConfig(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'Boris',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
26
tests/TestKernel.php
Normal file
26
tests/TestKernel.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\ExampleBundle\Tests;
|
||||
|
||||
use Pcm\ExampleBundle\PcmExampleBundle;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
final class TestKernel extends Kernel
|
||||
{
|
||||
public function registerBundles(): array
|
||||
{
|
||||
return [
|
||||
new PcmExampleBundle()
|
||||
];
|
||||
}
|
||||
|
||||
public function registerContainerConfiguration(LoaderInterface $loader): void
|
||||
{
|
||||
// Ignore this
|
||||
// $loader->load(__DIR__.'/../config/packages/pcm_example.yaml');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user