Milan Felix Šulc
📦 Package maker • 👷 Architect ModernTV • 🐘 PHP enthusiast • 💿 Multimedia engineer • 👨👩👧👦 Father • ☕️ Coffee-based
26.01.2019
@xf3l1x
@nettefw
github.com/planette/nutella-project
composer require symfony/console
# bin/console.php
<?php
require __DIR__.'/vendor/autoload.php';
use Symfony\Component\Console\Application;
$application = new Application();
$application->add(new HelloCommand());
$application->run();
class HelloCommand extends Command
{
protected function configure(): void
{
$this->setName('hello');
}
protected function execute(InputInterface $input, OutputInterface $output): void
{
// magic goes here
}
}
# config.neon
services:
console.application:
class: Symfony\Component\Console\Application
setup:
- setAutoExit(true)
- setName("Nutella project")
- setVersion("1.0")
- add(App\Console\HelloCommand())
#!/usr/bin/env php
<?php
/** @var Nette\DI\Container $container */
$container = require_once __DIR__ . '/../app/bootstrap.php';
// Run application.
$container->getByType(Symfony\Component\Console\Application::class)->run();
Nutella Project 1.0
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
help Displays help for a command
list Lists commands
hello Hello world!
# config.neon
extensions:
console: Contributte\Console\DI\ConsoleExtension(%consoleMode%)
console:
name: Nutella
version: "1.0"
url: http://localhost/
lazy: true
composer require contributte/console
# config.neon
extensions:
console: Contributte\Console\DI\ConsoleExtension(%consoleMode%)
console.extra: Contributte\Console\Extra\DI\ConsoleBridgesExtension
console:
name: Nutella
version: "1.0"
url: http://localhost/
lazy: true
composer require contributte/console-extra
nette
nette:cache:purge Clear temp folders and others
nette:caching:clear Clear Nette Caching Storage
nette:di:purge Clear temp/cache/Nette.Configurator folder
nette:latte:purge Clear temp/latte folder
nette:latte:warmup Warmup Latte templates (*.latte)
nette:router:dump Display all defined routes
nette:security:password Generates password (s) using Nette Passwords
nette:utils:random Generates random string(s) using Nette Random
composer require symfony/event-dispatcher
<?php
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
$dispatcher->addListener('order.created', function (Event $event) {
// Hey, we have an order!
});
$dispatcher->addListener('order.created', [$listener, 'onOrderCreated']);
<?php
use Symfony\Component\EventDispatcher\Event;
class OrderListener
{
public function onOrderCreated(Event $event): void
{
// Hey, we have an order!
}
}
# config.neon
services:
events.dispatcher:
class: Symfony\Component\EventDispatcher\EventDispatcher
setup:
- addListener('order.created', App\Model\OrderListener())
use Nette\Application\UI\Form;
use Symfony\Component\EventDispatcher\EventDispatcher;
class OrderPresenter
{
private $dispatcher;
public function __construct(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function saveOrder(Form $form): void
{
// Some logic..
$this->dispatcher->dispatch('order.created', new OrderEvent($order));
}
}
# config.neon
extensions:
events: Contributte\EventDispatcher\DI\EventDispatcherExtension
composer require contributte/event-dispatcher
<?php declare(strict_types = 1);
namespace App\Model\Order;
use App\Domain\Order\Event\OrderCreated;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Tracy\Debugger;
class OrderLogSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
OrderCreated::NAME => 'onOrderCreated',
];
}
public function onOrderCreated(OrderCreated $event): void
{
Debugger::log($event, 'info');
Debugger::barDump($event);
}
}
class OrderLogSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
OrderCreated::NAME => [
['onOrderCreatedBefore', 100],
['onOrderCreated', 0],
['onOrderCreatedAfter', -100],
],
];
}
public function onOrderCreatedBefore(OrderCreated $event): void
{
Debugger::log('BEFORE');
}
public function onOrderCreated(OrderCreated $event): void
{
Debugger::log($event, 'info');
}
public function onOrderCreatedAfter(OrderCreated $event): void
{
Debugger::log('AFTER');
}
}
{
"id": 1,
"username": "felix",
"email": "felix@nette.org",
"name": "Felix",
"surname": "Felicis"
}
github.com/planette/forest-project
composer require symfony/serializer
😢
$serializer = new Serializer(
[new PropertyNormalizer()],
[new JsonEncoder()]
);
$order = new Order(1);
$json = $serializer->serialize($order, 'json');
// {id: 1}
class Order
{
private $id;
public function __construct(int $id)
{
$this->id = $id;
}
public function getId(): int
{
return $this->id;
}
}
$serializer = new Serializer(
[new PropertyNormalizer()],
[new JsonEncoder()]
);
$json = '{"id":1}';
$obj = $serializer->deserialize($json, Order::class, 'json');
# config.neon
services:
symfony.serializer:
class: Symfony\Component\Serializer\Serializer(
[Symfony\Component\Serializer\Normalizer\ObjectNormalizer()],
[Symfony\Component\Serializer\Encoder\JsonEncoder()]
)
use Symfony\Component\Serializer\Serializer;
class ApiUserController
{
private $serializer;
public function __construct(Serializer $serializer)
{
$this->serializer = $serializer;
}
public function serialize(User $user)
{
$this->serializer->serialize($user, 'json');
}
public function deserialize($json)
{
$this->serializer->deserialize($json, User::class, 'json');
}
}
$serializer = new Serializer(
[new PropertyNormalizer()],
[new JsonEncoder()]
);
$user = new User();
$user->addOrder(new Order(1));
$user->addOrder(new Order(2));
$json = $serializer->serialize($order, 'json');
// {"orders":[{"id":1},{"id":2}]}
class Order
{
private $id;
public function __construct(int $id)
{
$this->id = $id;
}
public function getId(): int
{
return $this->id;
}
}
class User
{
/** @var Order[] */
private $orders = [];
public function addOrder(Order $order): void
{
$this->orders[] = $order;
}
public function getOrders(): array
{
return $this->orders;
}
}
$serializer = new Serializer(
[new PropertyNormalizer()],
[new JsonEncoder()]
);
$json = '{"orders":[{"id":1},{"id":2}]}';
$obj = $serializer->deserialize($json, User::class, 'json');
$serializer->serialize($obj, 'json', $context);
composer require symfony/validator
😢
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Validation;
$validator = Validation::createValidator();
$violations = $validator->validate('Felix', [
new Length(['min' => 10]),
new NotBlank(),
]);
// This value is too short.
// It should have 10 characters or more.
$user = new UserPojo();
$user->setUsername('Felix');
$validator = Validation::createValidatorBuilder()
->addMethodMapping('loadValidatorMetadata')
->getValidator();
$violations = $validator->validate($user);
// This value is too short.
// It should have 10 characters or more.
class UserPojo
{
/** @var string */
private $username;
// getter/setter
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('username', new NotBlank());
$metadata->addPropertyConstraint('username', new Length(['min' => 10, 'max' => 20]));
}
}
$user = new User('Felix');
$validator = Validation::createValidatorBuilder()
->enableAnnotationMapping()
->getValidator();
$violations = $validator->validate($user);
// This value is too short.
// It should have 10 characters or more.
class User
{
/**
* @var string
* @Assert\NotBlank
* @Assert\Length(min="10", max="20")
*/
private $username;
public function __construct(string $username)
{
$this->username = $username;
}
// getter
}
use Symfony\Component\Validator\Validator\ValidatorInterface;
class ApiUserCreator
{
private $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function doMagic()
{
$violations = $this->validator->validate($user)
}
}
// config.neon
services:
symfony.validator:
class: Symfony\Component\Validator\Validator\ValidatorInterface
factory: @symfony.validator.builder::getValidator()
symfony.validator.builder:
class: Symfony\Component\Validator\ValidatorBuilder
factory: Symfony\Component\Validator\Validation
::createValidatorBuilder()
::enableAnnotationMapping()
±48 😎
class User
{
/**
* @Assert\NotBlank(payload={"severity"="error"})
*/
protected $username;
/**
* @Assert\NotBlank(payload={"severity"="error"})
*/
protected $password;
/**
* @Assert\Iban(payload={"severity"="warning"})
*/
protected $bankAccountNumber;
}
Kdyby\Doctrine
nettrine/orm
Kdyby\Console
contributte/console
Kdyby\Events
contributte/event-dispatcher
contributte/console-extra
nettrine/dbal
contributte/event-dispatcher-extra
Lidi mi
píšou
5.2.2019
Milan Šulc — Vue.js, pomocník nejen s novou single page aplikací
enjoy PoSobota
🍻
@xf3l1x
By Milan Felix Šulc
📦 Package maker • 👷 Architect ModernTV • 🐘 PHP enthusiast • 💿 Multimedia engineer • 👨👩👧👦 Father • ☕️ Coffee-based