Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

POPO - plain old PHP object. Generate Data Structures / Data Transfer Objects from a schema.

License

NotificationsYou must be signed in to change notification settings

oliwierptak/popo

Repository files navigation

Build and run tests

POPO - "Plain Old Php Object" was inspired by "Plain Old Java Object" (POJO) concept.

POPO generator can also locate, load, validate, and combine schemas to create PHP source code files, representingArrays / Data Structures / Data Transfer Objects / Doctrine ORM Entities / MongoDB ODM Documents.

POPO Schema can be defined and extended on few levels, and it can be defined in multiple files.

Examples

Single schema file

Simple schema in YAML format, describing properties and relations of POPO objects.

#example.popo.yml$:config:namespace:App\Example\ReadmeoutputPath:tests/Example:Foo:property:[{name: title}{name: bar, type: popo, default: Bar::class}]Bar:property:[{name: title}]

Multiple schema files

The same example can be split into multiple files. However, this time, it's theBar that modifies theFoo definition.

#foo.popo.ymlExample:Foo:property:[{name: title}]
#bar.popo.ymlExample:Foo:property:[{name: bar, type: popo, default: Bar::class}]Bar:property:[{name: title}]

The generated code is the same, but the schema dependencies are inverted.

In both cases,Foo object usesBar object as its dependency, and they are both defined underExample schema name.

Generated code usage examples

Instantiate data structure from an array.

useApp\Example\Readme\Foo;$data = ['title' =>'A title','bar' => ['title' =>'Bar lorem ipsum',    ],];$foo = (newFoo)->fromArray($data);echo$foo->getTitle();echo$foo->requireBar()->getTitle();

Output:

A titleBar lorem ipsum

Display hierarchy of objects as an array.

useApp\Example\Readme\Foo;$foo = (newFoo);$foo->requireBar()->setTitle('new value');print_r($foo->toArray());

Output:

[    'title' => null,    'bar' => [        'title' => 'new value',    ],];

Runbin/popo generate -s tests/fixtures/popo-readme.yml ordocker-popo generate -s tests/fixtures/popo-readme.yml to generate files from this example.

Installation

composer require popo/generator --dev

Note: The installation can be skipped when using docker, seeDocker support section.

Usage

You can either use it as composer dependency or as docker command.

  1. Define schema file, seetests/fixtures for examples.

  2. Generate POPO files, run:

    • with composer

      vendor/bin/popo generate -s<schema-path> -o<output-path>
    • with docker

      docker-popo generate -s<schema-path> -o<output-path>

For example:bin/popo generate -s tests/fixtures/popo.yml ordocker-popo generate -s tests/fixtures/popo.yml.

POPO Schema

POPO Schema can be defined and extended on few levels- and it can be defined in multiple files.

The schema supports key mapping- inheritance- collections and encapsulation of other POPO objects.

Schema Definition

$:# file-config, shared configuration for all POPO objects in current schema fileconfig:namespace:stringoutputPath:stringnamespaceRoot:string|null# if set remaps namespace and outputPathextend:string|null# which class POPO objects should extend fromimplement:string|null# which interface POPO objects should implementcomment:string|null# Class docblock commentphpComment:string|null# Generated PHP File docblock commentuse:array<string>|[]# Import block in generated PHP classtrait:array<string>|[]# Traits to be used with generated classattribute:string|null# Class attributes as stringattributes:array<key, value>|[]# Class attributes as key value pairsclassPluginCollection:array<string>|[]phpFilePluginCollection:array<string>|[]namespacePluginCollection:array<string>|[]propertyPluginCollection:array<string>|[]mappingPolicyPluginCollection:array<string>|[]default:array# default valuesproperty:array# shared propertiesSchemaName:# schema-config$:# shared configuration for all POPO objects in SchemaName, in all schema filesconfig:namespace:stringoutputPath:stringnamespaceRoot:string|nullextend:string|nullimplement:string|nullcomment:string|nullphpComment:string|nulluse:array<string>|[]trait:array<string>|[]attribute:string|null,attributes:array<key, value>|[]classPluginCollection:array<string>|[]phpFilePluginCollection:array<string>|[]namespacePluginCollection:array<string>|[]propertyPluginCollection:array<string>|[]mappingPolicyPluginCollection:array<string>|[]default:arrayproperty:[{name:string,type:type:stringdefault:stringsupportedTypes:['array','bool','float','int','string','mixed','const','popo', 'datetime'],comment:string|null,default:mixed,itemType:string|null,itemName:string|null,extra:{timezone: ..., format: ...},attribute:string|null,attributes:array<key, value>|[]mappingPolicy:['none', 'lower', 'upper', 'camel-to-snake', 'snake-to-camel'],mappingPolicyValue:string|null}]PopoName:# popo-configconfig:namespace:stringoutputPath:stringnamespaceRoot:string|nullextend:string|nullimplement:string|nullcomment:string|nullphpComment:string|nulluse:array<string>|[]trait:array<string>|[]attribute:string|null,attributes:array<key, value>|[]classPluginCollection:array<string>|[]phpFilePluginCollection:array<string>|[]namespacePluginCollection:array<string>|[]propertyPluginCollection:array<string>|[]mappingPolicyPluginCollection:array<string>|[]default:arrayproperty:[{name:string,type:type:stringdefault:stringsupportedTypes:['array','bool','float','int','string','mixed','const','popo', 'datetime'],comment:string|null,default:mixed,itemType:string|null,itemName:string|null,extra:{timezone: ..., format: ...},attribute:string|null,attributes:array<key, value>|[]mappingPolicy:['none', 'lower', 'upper', 'camel-to-snake', 'snake-to-camel'],mappingPolicyValue:string|null}]

Schema configuration options

namespace

Defines generated class namespace.

config:namespace:App\Example...

outputPath

Defines output directory.

config:outputPath:src/...

namespaceRoot

Defines the begging ofoutputPath that should be removed.For example to generated files undersrc/Example withApp\Example namespace.

config:namespace:App\ExampleoutputPath:src/namespaceRoot:App\...

extend

Which class should the generated class extend from. Must start with\ or contain::class.

config:extend:\App\Example\AbstractDto::class...

implement

Which interface should the generated class implement. Must start with\ or contain::class.

config:implement:\App\Example\DtoInterface::class...

comment

Class comment.

config:comment:|    @Document(collection="events")...

phpComment

Generated PHP file comment.

config:phpComment:|    Auto generated.    @SuppressWarnings(PHPMD)    @phpcs:ignoreFile...

use

Import statements.

config:use:      -Doctrine\ODM\MongoDB\Mapping\Annotations\Document      -Doctrine\ODM\MongoDB\Mapping\Annotations\Field      -Doctrine\ODM\MongoDB\Mapping\Annotations\Id...

trait

Traits statements.

config:trait:      -App\Example\MyTrait...

attribute

Class attributes value.

config:attribute:|      #[Doctrine\ORM\Mapping\Entity(repositoryClass: LogEventRepository::class)]...

attributes:array

Attribute value as collection. Supported values:

  • name
  • value:mixed
config:attributes:      -name:Doctrine\ORM\Mapping\Entityvalue:{repositoryClass: LogEventRepository::class}...

classPluginCollection:array

Additional plugins used to generate methods.

config:classPluginCollection:      -\App\Plugin\ExampleMethodPopoPlugin::class...

namespacePluginCollection:array

Additional plugins used to generate namespace block.

config:namespacePluginCollection:      -\App\Plugin\ExampleNamespacePopoPlugin::class...

propertyPluginCollection:array

Additional plugins used to generate properties.

config:propertyPluginCollection:      -\App\Plugin\ExamplePropertyPopoPlugin::class...

mappingPolicyPluginCollection:array

Set of plugins used to map property names, e.g.fooId =>FOO_ID.

config:mappingPolicyPluginCollection:      -\App\Plugin\SpecialCaseMappingPopoPlugin::class...

Property configuration options

name

The name of the property. The property related methods will be generated based on this value. For examplegetFooBar().This is required parameter.

property:   -name:title...

type

Property data type, supported are:

  • array
  • bool
  • float
  • int
  • string
  • mixed
  • const
  • popo
  • datetime

Default property type isstring.

property:   -name:precisiontype:float...

comment

Docblock value for property and methods.

property:   -name:titlecomment:Lorem ipsum...

default: mixed

Default value.

property:   -name:itemsdefault:\App\ExampleInterface::TEST_BUZZ...

extra: array

Used bydatetime data type. Supported values:

  • format
  • timezone
property:     -name:createdtype:datetimeextra:timezone:Europe/Parisformat:D, d M y H:i:s O...

itemType

Used byarray data type together withitemName element. Describes type of single array element.

property:    -name:productstype:arrayitemType:Product::class...

itemName

Used byarray data type. Describes name of single array element. For example:setProducts(array $products),addProduct(Product $item).

property:    -name:productstype:arrayitemName:product...

attribute

Attribute value.

property:    -name:priceattribute:|#[Doctrine\ORM\Mapping\Column(type: Types::INTEGER)]...

attributes:array

Attribute value as collection. Supported values:

  • name
  • value:mixed
property:    -name:idattributes:        -name:Doctrine\ORM\Mapping\Columnvalue:['length: 255']...

mappingPolicy: array

Dynamically remaps property names, for example,fooId =>FOO_ID. Supported values:

  • none
  • lower
  • upper
  • camel-to-snake
  • snake-to-camel
property:  -name:fooIdmappingPolicy:      -camel-to-snake      -upper...

mappingPolicyValue

Statically remaps property names, for example,fooId =>FOO_ID.

property:  -name:fooIdmappingPolicyValue:FOO_ID...

Schema Inheritance

Thepopo-config values overrideschema-file-config values- andschema-file-config values overwriteschema-config values.

On top of that there is aglobal-config that is defined when using--schemaConfigFilename parameter.

POPO Schema

schema-config

The configuration was defined as aSchema property.It will be used byall POPO objects inall files under given schema.

schema-file-config

The configuration was defined as aSchemaFile property.It will be used byall POPO objects incurrent file.

popo-config

The configuration was defined as aPOPO property.It will be used by onespecific POPO objects incurrent file.

Seetests/fixtures for schema examples.

Property name remapping

POPO can remap property keys names, for example changefoo_id intofooId.

SeeProperty Name Remapping doc.

Pluggable architecture

New functionality can be provided on the command line, or via configuration.

SeePlugins doc.

Doctrine Support

SeeDoctrine Support doc.

Command line options

SeeCommand Line Options doc.

More Examples

Seefixtures andtests for more usage examples.

Composer script

Add popo scrip to composer and runcomposer popo in a project.

    "scripts": {        "popo": [            "bin/popo generate -s <schema-path>"        ]    },    "scripts-descriptions": {        "popo": "Generate POPO files"    }

Docker support

With docker you can generate files without installingPOPO as dependency in the project.

docker container run -it --rm oliwierptak/popo /app/bin/popo

You can either run the command directly, or create an alias, e.g.:

alias docker-popo='docker container run -it --rm oliwierptak/popo /app/bin/popo ${@}'

For example:

docker-popo generate -s tests/fixtures/popo.ymldocker-popo report -s tests/fixtures/popo.yml

See also:bin/docker-popo.

PHP version compatibility

  • POPOv1.x - PHP 7.2+
  • POPOv2.x - PHP 7.2+
  • POPOv3.x - PHP 7.4+
  • POPOv4.x - PHP 7.4+
  • POPOv5.x - PHP 7.4+
  • POPOv6.x - PHP 8+

POPO schema example

Schema example that produces generatedPopoConfigurator class.

$:config:namespace:PopooutputPath:src/phpComment:|      @SuppressWarnings(PHPMD)      @phpcs:ignoreFilePopo:PopoConfigurator:default:phpFilePluginCollection:        -\Popo\Plugin\PhpFilePlugin\StrictTypesPhpFilePlugin::class        -\Popo\Plugin\PhpFilePlugin\CommentPhpFilePlugin::classnamespacePluginCollection:        -\Popo\Plugin\NamespacePlugin\UseStatementPlugin::classclassPluginCollection:        -\Popo\Plugin\ClassPlugin\ClassAttributePlugin::class        -\Popo\Plugin\ClassPlugin\ClassCommentPlugin::class        -\Popo\Plugin\ClassPlugin\ConstPropertyClassPlugin::class        -\Popo\Plugin\ClassPlugin\DateTimeMethodClassPlugin::class        -\Popo\Plugin\ClassPlugin\ExtendClassPlugin::class        -\Popo\Plugin\ClassPlugin\ImplementClassPlugin::class        -\Popo\Plugin\ClassPlugin\IsNewClassPlugin::class        -\Popo\Plugin\ClassPlugin\ListModifiedPropertiesClassPlugin::class        -\Popo\Plugin\ClassPlugin\MetadataClassPlugin::class        -\Popo\Plugin\ClassPlugin\ModifiedToArrayClassPlugin::class        -\Popo\Plugin\ClassPlugin\PopoMethodClassPlugin::class        -\Popo\Plugin\ClassPlugin\RequireAllClassPlugin::class        -\Popo\Plugin\ClassPlugin\UpdateMapClassPlugin::class        -\Popo\Plugin\ClassPlugin\FromArrayClassPlugin::class        -\Popo\Plugin\ClassPlugin\FromMappedArrayClassPlugin::class        -\Popo\Plugin\ClassPlugin\ToArrayClassPlugin::class        -\Popo\Plugin\ClassPlugin\ToMappedArrayClassPlugin::class        -\Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArrayLowercasePlugin::class        -\Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArrayUppercasePlugin::class        -\Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArraySnakeToCamelPlugin::class        -\Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArrayCamelToSnakePlugin::classpropertyPluginCollection:        -\Popo\Plugin\PropertyPlugin\AddItemPropertyMethodPlugin::class        -\Popo\Plugin\PropertyPlugin\DefinePropertyPlugin::class        -\Popo\Plugin\PropertyPlugin\GetPropertyMethodPlugin::class        -\Popo\Plugin\PropertyPlugin\HasPropertyMethodPlugin::class        -\Popo\Plugin\PropertyPlugin\RequirePropertyMethodPlugin::class        -\Popo\Plugin\PropertyPlugin\SetPropertyMethodPlugin::classmappingPolicyPluginCollection:none:\Popo\Plugin\MappingPolicy\NoneMappingPolicyPlugin::classlower:\Popo\Plugin\MappingPolicy\LowerMappingPolicyPlugin::classupper:\Popo\Plugin\MappingPolicy\UpperMappingPolicyPlugin::classsnake-to-camel:\Popo\Plugin\MappingPolicy\SnakeToCamelMappingPolicyPlugin::classcamel-to-snake:\Popo\Plugin\MappingPolicy\CamelToSnakeMappingPolicyPlugin::classproperty:[{name: schemaPath}{name: namespace}{name: namespaceRoot}{name: outputPath}{name: phpFilePluginCollection, type: array, itemType: string, itemName: phpFilePluginClass}{name: namespacePluginCollection, type: array, itemType: string, itemName: namespacePluginClass}{name: classPluginCollection, type: array, itemType: string, itemName: classPluginClass}{name: propertyPluginCollection, type: array, itemType: string, itemName: propertyPluginClass}{name: mappingPolicyPluginCollection, type: array, itemType: string, itemName: mappingPolicyPluginClass}{name: schemaConfigFilename}{name: schemaPathFilter}{name: schemaFilenameMask, default: '*.popo.yml'}{name: shouldIgnoreNonExistingSchemaFolder, type: bool}]}}

[8]ページ先頭

©2009-2025 Movatter.jp