├── .gitignore ├── tests ├── bootstrap.php └── Mandango │ └── Mondator │ └── Tests │ ├── Definition │ ├── ConstantTest.php │ ├── PropertyTest.php │ ├── MethodTest.php │ └── DefinitionTest.php │ ├── Fixtures │ └── Extension │ │ ├── Name.php │ │ ├── ProcessOthersFromArray.php │ │ ├── Twig │ │ ├── MandangoTestsTwigExtension.php │ │ └── templates │ │ │ └── defining.php │ │ ├── InitDefinition.php │ │ ├── AddProperty.php │ │ └── NewConfigClass.php │ ├── DumperTest.php │ ├── DefinitionTest.php │ ├── OutputTest.php │ ├── ContainerTest.php │ ├── MondatorTest.php │ └── ExtensionTest.php ├── .travis.yml ├── README.md ├── CHANGELOG ├── phpunit.xml.dist ├── src └── Mandango │ └── Mondator │ ├── Definition │ ├── Constant.php │ ├── Property.php │ ├── Method.php │ └── Definition.php │ ├── Definition.php │ ├── Output.php │ ├── Extension.php │ ├── Container.php │ ├── Dumper.php │ ├── Mondator.php │ └── ClassExtension.php ├── composer.json ├── LICENSE └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | phpunit.xml 3 | /vendor/ 4 | .phpunit.result.cache 5 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | add('Mandango\Mondator\Tests', __DIR__); -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | 7 | before_script: 8 | - composer --dev --prefer-source install 9 | 10 | script: phpunit -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mondator 2 | 3 | Mondator is an easy and flexible class generator for PHP. 4 | 5 | ## Documentation 6 | 7 | See the documentation in [http://mandango.org/doc/](http://mandango.org/doc/) 8 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 1.0.0 BETA2 - 18/5/2011 2 | ----------------------- 3 | 4 | * [e0bad9d] added README 5 | * [2037709] changed some getters 6 | * [61f979d] added @api phpdoc tag 7 | * [ef3b967] changed some properties and methods to private 8 | * [d758cda] changed license to MIT and files header 9 | * [9c78b69] moved symfony class loader submodule 10 | * [ca6812c] importing 11 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ./tests/ 7 | 8 | 9 | 10 | 11 | 12 | ./src 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Definition/Constant.php: -------------------------------------------------------------------------------- 1 | name = $name; 13 | $this->value = $value; 14 | } 15 | 16 | public function getName() 17 | { 18 | return $this->name; 19 | } 20 | 21 | public function getValue() 22 | { 23 | return $this->value; 24 | } 25 | } -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Definition/ConstantTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($constant->getName(), self::IRRELEVANT_NAME); 18 | $this->assertEquals($constant->getValue(), self::IRRELEVANT_VALUE); 19 | } 20 | } -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Fixtures/Extension/Name.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Fixtures\Extension; 13 | 14 | use Mandango\Mondator\Extension; 15 | use Mandango\Mondator\Definition; 16 | use Mandango\Mondator\Output; 17 | 18 | class Name extends Extension 19 | { 20 | protected function doClassProcess() 21 | { 22 | $this->definitions['name'] = new Definition($this->configClass['name'], new Output(sys_get_temp_dir())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Fixtures/Extension/ProcessOthersFromArray.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Fixtures\Extension; 13 | 14 | use Mandango\Mondator\Extension; 15 | 16 | class ProcessOthersFromArray extends Extension 17 | { 18 | protected function doNewClassExtensionsProcess() 19 | { 20 | if (isset($this->configClass['extensions'])) { 21 | foreach ($this->configClass['extensions'] as $extension) { 22 | $this->newClassExtensions[] = $this->createClassExtensionFromArray($extension); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Fixtures/Extension/Twig/MandangoTestsTwigExtension.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Fixtures\Extension\Twig; 13 | 14 | use Mandango\Mondator\Extension; 15 | use Mandango\Mondator\Definition; 16 | use Mandango\Mondator\Output; 17 | 18 | class MandangoTestsTwigExtension extends Extension 19 | { 20 | protected function doClassProcess() 21 | { 22 | $this->definitions['document'] = new Definition($this->class, new Output(sys_get_temp_dir())); 23 | 24 | $this->processTemplate($this->definitions['document'], file_get_contents(__DIR__.'/templates/defining.php')); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongator/mondator", 3 | "description": "Easy and flexible class generator for PHP", 4 | "keywords": [ 5 | "class-generator" 6 | ], 7 | "type": "library", 8 | "license": "MIT", 9 | "authors": [ 10 | { 11 | "name": "Máximo Cuadros", 12 | "email": "maximo@yunait.com" 13 | }, 14 | { 15 | "name": "Pablo Díez", 16 | "email": "pablodip@gmail.com" 17 | }, 18 | { 19 | "name": "Ádám Bálint", 20 | "email": "adam.balint@srg.hu" 21 | } 22 | ], 23 | "require": { 24 | "php": "^8.1", 25 | "twig/twig": "^3.15" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "^10.5" 29 | }, 30 | "autoload": { 31 | "psr-0": { 32 | "Mandango\\Mondator\\": "src/" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Fixtures/Extension/InitDefinition.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Fixtures\Extension; 13 | 14 | use Mandango\Mondator\Extension; 15 | use Mandango\Mondator\Definition; 16 | use Mandango\Mondator\Output; 17 | 18 | class InitDefinition extends Extension 19 | { 20 | protected function setUp() 21 | { 22 | $this->addRequiredOptions(array( 23 | 'definition_name', 24 | 'class_name', 25 | )); 26 | } 27 | 28 | protected function doClassProcess() 29 | { 30 | $this->definitions[$this->getOption('definition_name')] = new Definition($this->getOption('class_name'), new Output(sys_get_temp_dir())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/DumperTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests; 13 | 14 | use Mandango\Mondator\Definition\Definition; 15 | use Mandango\Mondator\Dumper; 16 | use PHPUnit\Framework\TestCase; 17 | 18 | class DumperTest extends TestCase 19 | { 20 | public function testConstructor() 21 | { 22 | $definition = new Definition('Class1'); 23 | 24 | $dumper = new Dumper($definition); 25 | $this->assertSame($definition, $dumper->getDefinition()); 26 | } 27 | 28 | public function testDefinition() 29 | { 30 | $definition1 = new Definition('Class1'); 31 | $definition2 = new Definition('Class2'); 32 | 33 | $dumper = new Dumper($definition1); 34 | $dumper->setDefinition($definition2); 35 | $this->assertSame($definition2, $dumper->getDefinition()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2011 Pablo Díez 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Fixtures/Extension/Twig/templates/defining.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests; 13 | 14 | use Mandango\Mondator\Definition; 15 | use Mandango\Mondator\Output; 16 | use PHPUnit\Framework\TestCase; 17 | 18 | class DefinitionTest extends TestCase 19 | { 20 | public function testConstructor() 21 | { 22 | $output = new Output('foo', true); 23 | $definition = new Definition('Model\User', $output); 24 | 25 | $this->assertSame('Model\User', $definition->getClass()); 26 | $this->assertSame($output, $definition->getOutput()); 27 | } 28 | 29 | public function testSetGetOutput() 30 | { 31 | $output1 = new Output('foo'); 32 | $output2 = new Output('bar'); 33 | 34 | $definition = new Definition('User', $output1); 35 | 36 | $this->assertSame($output1, $definition->getOutput()); 37 | $definition->setOutput($output2); 38 | $this->assertSame($output2, $definition->getOutput()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Fixtures/Extension/AddProperty.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Fixtures\Extension; 13 | 14 | use Mandango\Mondator\Definition\Definition; 15 | use Mandango\Mondator\Definition\Property; 16 | use Mandango\Mondator\Extension; 17 | 18 | class AddProperty extends Extension 19 | { 20 | protected $options = array( 21 | 'definition' => null, 22 | 'visibility' => null, 23 | 'name' => null, 24 | 'value' => null, 25 | ); 26 | 27 | protected function setUp() 28 | { 29 | $this->addRequiredOptions(array( 30 | 'definition', 31 | 'visibility', 32 | 'name', 33 | 'value', 34 | )); 35 | } 36 | 37 | protected function doClassProcess() 38 | { 39 | $property = new Property($this->getOption('visibility'), $this->getOption('name'), $this->getOption('value')); 40 | 41 | $this->definitions[$this->getOption('definition')]->addProperty($property); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/OutputTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests; 13 | 14 | use Mandango\Mondator\Output; 15 | use PHPUnit\Framework\TestCase; 16 | 17 | class OutputTest extends TestCase 18 | { 19 | public function testConstructor() 20 | { 21 | $output = new Output('foo', true); 22 | $this->assertEquals('foo', $output->getDir()); 23 | $this->assertTrue($output->getOverride()); 24 | } 25 | 26 | public function testDir() 27 | { 28 | $output = new Output('foo'); 29 | $this->assertEquals('foo', $output->getDir()); 30 | $output->setDir('bar'); 31 | $this->assertEquals('bar', $output->getDir()); 32 | } 33 | 34 | public function testOverride() 35 | { 36 | $output = new Output('foo'); 37 | $this->assertFalse($output->getOverride()); 38 | $output->setOverride(true); 39 | $this->assertTrue($output->getOverride()); 40 | $output->setOverride(1); 41 | $this->assertTrue($output->getOverride()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Definition.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator; 13 | 14 | use Mandango\Mondator\Definition\Definition as BaseDefinition; 15 | 16 | /** 17 | * Definitions to save with the extensions. Allows save the output. 18 | * 19 | * @author Pablo Díez 20 | * 21 | * @api 22 | */ 23 | class Definition extends BaseDefinition 24 | { 25 | private $output; 26 | 27 | /** 28 | * Constructor. 29 | * 30 | * @param string $class The class. 31 | * @param Mandango\Mondator\Output $output The output. 32 | * 33 | * @api 34 | */ 35 | public function __construct($class, Output $output) 36 | { 37 | parent::__construct($class); 38 | 39 | $this->setOutput($output); 40 | } 41 | 42 | /** 43 | * Set the output. 44 | * 45 | * @param Mandango\Mondator\Output $output The output. 46 | * 47 | * @api 48 | */ 49 | public function setOutput(Output $output) 50 | { 51 | $this->output = $output; 52 | } 53 | 54 | /** 55 | * Returns the output. 56 | * 57 | * @return Mandango\Mondator\Output The output. 58 | * 59 | * @api 60 | */ 61 | public function getOutput() 62 | { 63 | return $this->output; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Fixtures/Extension/NewConfigClass.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Fixtures\Extension; 13 | 14 | use Mandango\Mondator\ClassExtension; 15 | 16 | class NewConfigClass extends ClassExtension 17 | { 18 | protected function setUp() 19 | { 20 | $this->addRequiredOptions(array( 21 | 'suffix', 22 | 'name', 23 | )); 24 | 25 | $this->addOptions(array( 26 | 'multiple' => false, 27 | 'multiple_suffix' => null, 28 | 'multiple_name' => null, 29 | )); 30 | } 31 | 32 | protected function doNewConfigClassesProcess() 33 | { 34 | $newClassName = $this->class.$this->getOption('suffix'); 35 | 36 | $configClass = array( 37 | 'name' => $this->getOption('name'), 38 | ); 39 | 40 | if ($this->getOption('multiple')) { 41 | $configClass['extensions'][] = array( 42 | 'class' => 'Mandango\Mondator\Tests\Fixtures\Extension\NewConfigClass', 43 | 'options' => array( 44 | 'suffix' => $this->getOption('multiple_suffix'), 45 | 'name' => $this->getOption('multiple_name'), 46 | ), 47 | ); 48 | } 49 | 50 | $this->newConfigClasses[$newClassName] = $configClass; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Output.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator; 13 | 14 | /** 15 | * Represents a output for a definition. 16 | * 17 | * @author Pablo Díez 18 | * 19 | * @api 20 | */ 21 | class Output 22 | { 23 | private $dir; 24 | private $override; 25 | 26 | /** 27 | * Constructor. 28 | * 29 | * @param string $dir The dir. 30 | * @param bool $override The override. It indicate if override files (optional, false by default). 31 | * 32 | * @api 33 | */ 34 | public function __construct($dir, $override = false) 35 | { 36 | $this->setDir($dir); 37 | $this->setOverride($override); 38 | } 39 | 40 | /** 41 | * Set the dir. 42 | * 43 | * @param $string $dir The dir. 44 | * 45 | * @api 46 | */ 47 | public function setDir($dir) 48 | { 49 | $this->dir = $dir; 50 | } 51 | 52 | /** 53 | * Returns the dir. 54 | * 55 | * @return string The dir. 56 | * 57 | * @api 58 | */ 59 | public function getDir() 60 | { 61 | return $this->dir; 62 | } 63 | 64 | /** 65 | * Set the override. It indicate if override files. 66 | * 67 | * @param bool $override The override. 68 | * 69 | * @api 70 | */ 71 | public function setOverride($override) 72 | { 73 | $this->override = (bool) $override; 74 | } 75 | 76 | /** 77 | * Returns the override. 78 | * 79 | * @return bool The override. 80 | * 81 | * @api 82 | */ 83 | public function getOverride() 84 | { 85 | return $this->override; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Extension.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator; 13 | 14 | /** 15 | * Extension is the base class for extensions. 16 | * 17 | * @author Pablo Díez 18 | * 19 | * @api 20 | */ 21 | abstract class Extension extends ClassExtension 22 | { 23 | /** 24 | * Pre global process of the extension. 25 | * 26 | * @param \ArrayObject $configClasses The config classes. 27 | * @param Mandango\Mondator\Container $container The global container. 28 | * 29 | * @api 30 | */ 31 | public function preGlobalProcess(\ArrayObject $configClasses, Container $container) 32 | { 33 | $this->configClasses = $configClasses; 34 | $this->definitions = $container; 35 | 36 | $this->doPreGlobalProcess(); 37 | 38 | $this->configClasses = null; 39 | $this->definitions = null; 40 | } 41 | 42 | /** 43 | * Do the pre global process. 44 | * 45 | * @api 46 | */ 47 | protected function doPreGlobalProcess() 48 | { 49 | } 50 | 51 | /** 52 | * Post global process of the extension. 53 | * 54 | * @param \ArrayObject $configClasses The config classes. 55 | * @param Mandango\Mondator\Container $container The global container. 56 | * 57 | * @api 58 | */ 59 | public function postGlobalProcess(\ArrayObject $configClasses, Container $container) 60 | { 61 | $this->configClasses = $configClasses; 62 | $this->definitions = $container; 63 | 64 | $this->doPostGlobalProcess(); 65 | 66 | $this->configClasses = null; 67 | $this->definitions = null; 68 | } 69 | 70 | /** 71 | * Do the post global process. 72 | * 73 | * @api 74 | */ 75 | protected function doPostGlobalProcess() 76 | { 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Definition/PropertyTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Definition; 13 | 14 | use Mandango\Mondator\Definition\Property; 15 | use PHPUnit\Framework\TestCase; 16 | 17 | class PropertyTest extends TestCase 18 | { 19 | public function testConstructor() 20 | { 21 | $property = new Property('protected', 'visibilities', array('public', 'protected')); 22 | 23 | $this->assertSame('protected', $property->getVisibility()); 24 | $this->assertSame('visibilities', $property->getName()); 25 | $this->assertSame(array('public', 'protected'), $property->getValue()); 26 | } 27 | 28 | public function testVisibility() 29 | { 30 | $property = new Property('protected', 'visibilities', array('public', 'protected')); 31 | 32 | $property->setVisibility('public'); 33 | $this->assertSame('public', $property->getVisibility()); 34 | } 35 | 36 | public function testName() 37 | { 38 | $property = new Property('protected', 'visibilities', array('public', 'protected')); 39 | 40 | $property->setName('vs'); 41 | $this->assertSame('vs', $property->getName()); 42 | } 43 | 44 | public function testValue() 45 | { 46 | $property = new Property('protected', 'visibilities', array('public', 'protected')); 47 | 48 | $property->setValue('public;protected;private'); 49 | $this->assertSame('public;protected;private', $property->getValue()); 50 | } 51 | 52 | public function testStatic() 53 | { 54 | $property = new Property('protected', 'visibilities', array('public', 'protected')); 55 | 56 | $this->assertFalse($property->isStatic()); 57 | $property->setStatic(true); 58 | $this->assertTrue($property->isStatic()); 59 | } 60 | 61 | public function testDocComment() 62 | { 63 | $property = new Property('protected', 'visibilities', array('public', 'protected')); 64 | 65 | $property->setDocComment('myDoc'); 66 | $this->assertSame('myDoc', $property->getDocComment()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Definition/MethodTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Definition; 13 | 14 | use Mandango\Mondator\Definition\Method; 15 | use PHPUnit\Framework\TestCase; 16 | 17 | class MethodTest extends TestCase 18 | { 19 | public function testConstructor() 20 | { 21 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 22 | 23 | $this->assertSame('public', $method->getVisibility()); 24 | $this->assertSame('setVisibility', $method->getName()); 25 | $this->assertSame('$visibility', $method->getArguments()); 26 | $this->assertSame('$this->visibility = $visibility;', $method->getCode()); 27 | } 28 | 29 | public function testVisibility() 30 | { 31 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 32 | 33 | $method->setVisibility('protected'); 34 | $this->assertSame('protected', $method->getVisibility()); 35 | } 36 | 37 | public function testName() 38 | { 39 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 40 | 41 | $method->setName('setV'); 42 | $this->assertSame('setV', $method->getName()); 43 | } 44 | 45 | public function testArguments() 46 | { 47 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 48 | 49 | $method->setArguments('$v'); 50 | $this->assertSame('$v', $method->getArguments()); 51 | } 52 | 53 | public function testCode() 54 | { 55 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 56 | 57 | $method->setCode('$this->visibility = $v;'); 58 | $this->assertSame('$this->visibility = $v;', $method->getCode()); 59 | } 60 | 61 | public function testFinal() 62 | { 63 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 64 | 65 | $this->assertFalse($method->isFinal()); 66 | $method->setFinal(true); 67 | $this->assertTrue($method->isFinal()); 68 | } 69 | 70 | public function testStatic() 71 | { 72 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 73 | 74 | $this->assertFalse($method->isStatic()); 75 | $method->setStatic(true); 76 | $this->assertTrue($method->isStatic()); 77 | } 78 | 79 | public function testAbstract() 80 | { 81 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 82 | 83 | $this->assertFalse($method->isAbstract()); 84 | $method->setAbstract(true); 85 | $this->assertTrue($method->isAbstract()); 86 | } 87 | 88 | public function testDocComment() 89 | { 90 | $method = new Method('public', 'setVisibility', '$visibility', '$this->visibility = $visibility;'); 91 | 92 | $method->setDocComment('myDoc'); 93 | $this->assertSame('myDoc', $method->getDocComment()); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Definition/Property.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Definition; 13 | 14 | /** 15 | * Represents a property of a class. 16 | * 17 | * @author Pablo Díez 18 | * 19 | * @api 20 | */ 21 | class Property 22 | { 23 | private $visibility; 24 | private $name; 25 | private $value; 26 | private $static; 27 | private $docComment; 28 | 29 | /** 30 | * Constructor. 31 | * 32 | * @param string $visibility The visibility. 33 | * @param string $name The name. 34 | * @param mixed $value The value. 35 | * 36 | * @api 37 | */ 38 | public function __construct($visibility, $name, $value) 39 | { 40 | $this->setVisibility($visibility); 41 | $this->setName($name); 42 | $this->setValue($value); 43 | $this->static = false; 44 | } 45 | 46 | /** 47 | * Set the visibility. 48 | * 49 | * @param string $visibility The visibility. 50 | * 51 | * @api 52 | */ 53 | public function setVisibility($visibility) 54 | { 55 | $this->visibility = $visibility; 56 | } 57 | 58 | /** 59 | * Returns the visibility. 60 | * 61 | * @return string The visibility. 62 | * 63 | * @api 64 | */ 65 | public function getVisibility() 66 | { 67 | return $this->visibility; 68 | } 69 | 70 | /** 71 | * Set the name. 72 | * 73 | * @param string $name The name. 74 | * 75 | * @api 76 | */ 77 | public function setName($name) 78 | { 79 | $this->name = $name; 80 | } 81 | 82 | /** 83 | * Returns the name. 84 | * 85 | * @return string The name. 86 | * 87 | * @api 88 | */ 89 | public function getName() 90 | { 91 | return $this->name; 92 | } 93 | 94 | /** 95 | * Set the value. 96 | * 97 | * @param mixed $value The value. 98 | * 99 | * @api 100 | */ 101 | public function setValue($value) 102 | { 103 | $this->value = $value; 104 | } 105 | 106 | /** 107 | * Returns the value. 108 | * 109 | * @return mixed The value. 110 | * 111 | * @api 112 | */ 113 | public function getValue() 114 | { 115 | return $this->value; 116 | } 117 | 118 | /** 119 | * Set if the property is static. 120 | * 121 | * @param bool $static If the property is static. 122 | * 123 | * @api 124 | */ 125 | public function setStatic($static) 126 | { 127 | $this->static = (bool) $static; 128 | } 129 | 130 | /** 131 | * Return if the property is static. 132 | * 133 | * @return bool Returns if the property is static. 134 | * 135 | * @api 136 | */ 137 | public function isStatic() 138 | { 139 | return $this->static; 140 | } 141 | 142 | /** 143 | * Set the doc comment. 144 | * 145 | * @param string|null $docComment The doc comment. 146 | * 147 | * @api 148 | */ 149 | public function setDocComment($docComment) 150 | { 151 | $this->docComment = $docComment; 152 | } 153 | 154 | /** 155 | * Returns the doc comment. 156 | * 157 | * @return string|null The doc comment. 158 | * 159 | * @api 160 | */ 161 | public function getDocComment() 162 | { 163 | return $this->docComment; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Container.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator; 13 | 14 | /** 15 | * Container of definitions. 16 | * 17 | * @author Pablo Díez 18 | * 19 | * @api 20 | */ 21 | class Container implements \ArrayAccess, \Countable, \IteratorAggregate 22 | { 23 | private $definitions; 24 | 25 | /** 26 | * Constructor. 27 | * 28 | * @api 29 | */ 30 | public function __construct() 31 | { 32 | $this->definitions = array(); 33 | } 34 | 35 | /** 36 | * Returns if a definition name exists. 37 | * 38 | * @param string $name The definition name. 39 | * 40 | * @return bool Returns if the definition name exists. 41 | * 42 | * @api 43 | */ 44 | public function hasDefinition($name) 45 | { 46 | return isset($this->definitions[$name]); 47 | } 48 | 49 | /** 50 | * Set a definition. 51 | * 52 | * @param string $name The definition name. 53 | * 54 | * @api 55 | */ 56 | public function setDefinition($name, Definition $definition) 57 | { 58 | $this->definitions[$name] = $definition; 59 | } 60 | 61 | /** 62 | * Set the definitions. 63 | * 64 | * @param array $definitions An array of definitions. 65 | * 66 | * @api 67 | */ 68 | public function setDefinitions(array $definitions) 69 | { 70 | $this->definitions = array(); 71 | foreach ($definitions as $name => $definition) { 72 | $this->setDefinition($name, $definition); 73 | } 74 | } 75 | 76 | /** 77 | * Returns a definition by name. 78 | * 79 | * @param string $name The definition name. 80 | * 81 | * @return Definition The definition. 82 | * 83 | * @throws \InvalidArgumentException If the definition does not exists. 84 | * 85 | * @api 86 | */ 87 | public function getDefinition($name) 88 | { 89 | if (!$this->hasDefinition($name)) { 90 | throw new \InvalidArgumentException(sprintf('The definition "%s" does not exists.', $name)); 91 | } 92 | 93 | return $this->definitions[$name]; 94 | } 95 | 96 | /** 97 | * Returns the definitions. 98 | * 99 | * @return array The definitions. 100 | * 101 | * @api 102 | */ 103 | public function getDefinitions() 104 | { 105 | return $this->definitions; 106 | } 107 | 108 | /** 109 | * Remove a definition 110 | * 111 | * @param string $name The definition name 112 | * 113 | * @throws \InvalidArgumentException If the definition does not exists. 114 | * 115 | * @api 116 | */ 117 | public function removeDefinition($name) 118 | { 119 | if (!$this->hasDefinition($name)) { 120 | throw new \InvalidArgumentException(sprintf('The definition "%s" does not exists.', $name)); 121 | } 122 | 123 | unset($this->definitions[$name]); 124 | } 125 | 126 | /** 127 | * Clear the definitions. 128 | * 129 | * @api 130 | */ 131 | public function clearDefinitions() 132 | { 133 | $this->definitions = array(); 134 | } 135 | 136 | /* 137 | * \ArrayAccess interface. 138 | */ 139 | public function offsetExists(mixed $offset): bool 140 | { 141 | return $this->hasDefinition($offset); 142 | } 143 | 144 | public function offsetSet(mixed $offset, mixed $value): void 145 | { 146 | $this->setDefinition($offset, $value); 147 | } 148 | 149 | public function offsetGet(mixed $offset): mixed 150 | { 151 | return $this->getDefinition($offset); 152 | } 153 | 154 | public function offsetUnset(mixed $offset): void 155 | { 156 | $this->removeDefinition($offset); 157 | } 158 | 159 | /** 160 | * Returns the number of definitions (implements the \Countable interface). 161 | * 162 | * @return integer The number of definitions. 163 | * 164 | * @api 165 | */ 166 | public function count(): int 167 | { 168 | return count($this->definitions); 169 | } 170 | 171 | /** 172 | * Returns an \ArrayIterator with the definitions (implements \IteratorAggregate interface). 173 | * 174 | * @return \ArrayIterator An \ArrayIterator with the definitions. 175 | * 176 | * @api 177 | */ 178 | public function getIterator(): \Traversable 179 | { 180 | return new \ArrayIterator($this->definitions); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/ContainerTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests; 13 | 14 | use Mandango\Mondator\Container; 15 | use Mandango\Mondator\Definition; 16 | use Mandango\Mondator\Output; 17 | use PHPUnit\Framework\TestCase; 18 | 19 | class ContainerTest extends TestCase 20 | { 21 | public function testDefinitions() 22 | { 23 | $output = new Output('foo'); 24 | 25 | $definitions = array(); 26 | $definitions[1] = new Definition('Class1', $output); 27 | $definitions[2] = new Definition('Class2', $output); 28 | $definitions[3] = new Definition('Class3', $output); 29 | $definitions[4] = new Definition('Class4', $output); 30 | 31 | $container = new Container(); 32 | 33 | // setDefinition 34 | $container->setDefinition('definition1', $definitions[1]); 35 | $container->setDefinition('definition2', $definitions[2]); 36 | $this->assertSame(array( 37 | 'definition1' => $definitions[1], 38 | 'definition2' => $definitions[2], 39 | ), $container->getDefinitions()); 40 | 41 | // hasDefinition 42 | $this->assertTrue($container->hasDefinition('definition1')); 43 | $this->assertFalse($container->hasDefinition('definition3')); 44 | 45 | // getDefinition 46 | $this->assertSame($definitions[1], $container->getDefinition('definition1')); 47 | $this->assertSame($definitions[2], $container->getDefinition('definition2')); 48 | 49 | // setDefinitions 50 | $container->setDefinitions($setDefinitions = array( 51 | 'definition3' => $definitions[3], 52 | 'definition4' => $definitions[4] 53 | )); 54 | $this->assertSame($setDefinitions, $container->getDefinitions()); 55 | 56 | // removeDefinition 57 | $container->setDefinitions(array( 58 | 'definition1' => $definitions[1], 59 | 'definition2' => $definitions[2], 60 | 'definition3' => $definitions[3], 61 | 'definition4' => $definitions[4], 62 | )); 63 | $container->removeDefinition('definition2'); 64 | $this->assertFalse($container->hasDefinition('definition2')); 65 | $this->assertTrue($container->hasDefinition('definition1')); 66 | $this->assertTrue($container->hasDefinition('definition3')); 67 | $this->assertTrue($container->hasDefinition('definition4')); 68 | 69 | // clearDefinitions 70 | $container->clearDefinitions(); 71 | $this->assertSame(array(), $container->getDefinitions()); 72 | } 73 | 74 | public function testGetDefinitionNotExists() 75 | { 76 | $this->expectException(\InvalidArgumentException::class); 77 | $container = new Container(); 78 | $container->getDefinition('definition'); 79 | } 80 | 81 | public function testRemoveDefinitionNotExists() 82 | { 83 | $this->expectException(\InvalidArgumentException::class); 84 | $container = new Container(); 85 | $container->removeDefinition('definition'); 86 | } 87 | 88 | public function testArrayAccessInterface() 89 | { 90 | $output = new Output('foo'); 91 | 92 | $definition1 = new Definition('Class1', $output); 93 | $definition2 = new Definition('Class2', $output); 94 | 95 | $container = new Container(); 96 | 97 | // set 98 | $container['definition1'] = $definition1; 99 | $container['definition2'] = $definition2; 100 | 101 | // exists 102 | $this->assertTrue(isset($container['definition1'])); 103 | $this->assertFalse(isset($container['definition3'])); 104 | 105 | // get 106 | $this->assertSame($definition1, $container['definition1']); 107 | $this->assertSame($definition2, $container['definition2']); 108 | 109 | // unset 110 | unset($container['definition2']); 111 | $this->assertFalse(isset($container['definition2'])); 112 | $this->assertTrue(isset($container['definition1'])); 113 | } 114 | 115 | public function testCountableInterface() 116 | { 117 | $container = new Container(); 118 | $container->setDefinitions(array( 119 | new Definition('Class1', new Output('foo')), 120 | new Definition('Class2', new Output('bar')), 121 | )); 122 | 123 | $this->assertSame(2, $container->count()); 124 | $this->assertSame(2, count($container)); 125 | } 126 | 127 | public function testIteratorAggregateInterface() 128 | { 129 | $container = new Container(); 130 | $container->setDefinitions(array( 131 | new Definition('Class1', new Output('foo')), 132 | new Definition('Class2', new Output('bar')), 133 | )); 134 | 135 | $this->assertEquals(new \ArrayIterator($container->getDefinitions()), $container->getIterator()); 136 | $this->assertInstanceOf('\IteratorAggregate', $container); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Definition/Method.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Definition; 13 | 14 | /** 15 | * Represents a method of a class. 16 | * 17 | * @author Pablo Díez 18 | * 19 | * @api 20 | */ 21 | class Method 22 | { 23 | private $visibility; 24 | private $name; 25 | private $arguments; 26 | private $code; 27 | private $final; 28 | private $static; 29 | private $abstract; 30 | private $docComment; 31 | 32 | /** 33 | * Constructor. 34 | * 35 | * @param string $visibility The visibility. 36 | * @param string $name The name. 37 | * @param string $arguments The arguments (as string). 38 | * @param string $code The code. 39 | * 40 | * @api 41 | */ 42 | public function __construct($visibility, $name, $arguments, $code) 43 | { 44 | $this->setVisibility($visibility); 45 | $this->setName($name); 46 | $this->setArguments($arguments); 47 | $this->setCode($code); 48 | $this->final = false; 49 | $this->static = false; 50 | $this->abstract = false; 51 | } 52 | 53 | /** 54 | * Set the visibility. 55 | * 56 | * @param string $visibility The visibility. 57 | * 58 | * @api 59 | */ 60 | public function setVisibility($visibility) 61 | { 62 | $this->visibility = $visibility; 63 | } 64 | 65 | /** 66 | * Returns the visibility. 67 | * 68 | * @return string The visibility. 69 | * 70 | * @api 71 | */ 72 | public function getVisibility() 73 | { 74 | return $this->visibility; 75 | } 76 | 77 | /** 78 | * Set the name. 79 | * 80 | * @param string $name The name. 81 | * 82 | * @api 83 | */ 84 | public function setName($name) 85 | { 86 | $this->name = $name; 87 | } 88 | 89 | /** 90 | * Returns the name. 91 | * 92 | * @return string The name. 93 | * 94 | * @api 95 | */ 96 | public function getName() 97 | { 98 | return $this->name; 99 | } 100 | 101 | /** 102 | * Set the arguments. 103 | * 104 | * Example: "$argument1, &$argument2" 105 | * 106 | * @param string $arguments The arguments (as string). 107 | * 108 | * @api 109 | */ 110 | public function setArguments($arguments) 111 | { 112 | $this->arguments = $arguments; 113 | } 114 | 115 | /** 116 | * Returns the arguments. 117 | * 118 | * @api 119 | */ 120 | public function getArguments() 121 | { 122 | return $this->arguments; 123 | } 124 | 125 | /** 126 | * Set the code. 127 | * 128 | * @param string $code. 129 | * 130 | * @api 131 | */ 132 | public function setCode($code) 133 | { 134 | $this->code = $code; 135 | } 136 | 137 | /** 138 | * Returns the code. 139 | * 140 | * @return string The code. 141 | * 142 | * @api 143 | */ 144 | public function getCode() 145 | { 146 | return $this->code; 147 | } 148 | 149 | /** 150 | * Set if the method is final. 151 | * 152 | * @param bool $final If the method is final. 153 | * 154 | * @api 155 | */ 156 | public function setFinal($final) 157 | { 158 | $this->final = (bool) $final; 159 | } 160 | 161 | /** 162 | * Returns if the method is final. 163 | * 164 | * @return bool If the method is final. 165 | * 166 | * @api 167 | */ 168 | public function isFinal() 169 | { 170 | return $this->final; 171 | } 172 | 173 | /** 174 | * Set if the method is static. 175 | * 176 | * @param bool $static If the method is static. 177 | * 178 | * @api 179 | */ 180 | public function setStatic($static) 181 | { 182 | $this->static = (bool) $static; 183 | } 184 | 185 | /** 186 | * Return if the method is static. 187 | * 188 | * @return bool Returns if the method is static. 189 | * 190 | * @api 191 | */ 192 | public function isStatic() 193 | { 194 | return $this->static; 195 | } 196 | 197 | /** 198 | * Set if the method is abstract. 199 | * 200 | * @param bool $abstract If the method is abstract. 201 | * 202 | * @api 203 | */ 204 | public function setAbstract($abstract) 205 | { 206 | $this->abstract = (bool) $abstract; 207 | } 208 | 209 | /** 210 | * Return if the method is abstract. 211 | * 212 | * @return bool Returns if the method is abstract. 213 | * 214 | * @api 215 | */ 216 | public function isAbstract() 217 | { 218 | return $this->abstract; 219 | } 220 | 221 | /** 222 | * Set the doc comment. 223 | * 224 | * @param string|null $docComment The doc comment. 225 | * 226 | * @api 227 | */ 228 | public function setDocComment($docComment) 229 | { 230 | $this->docComment = $docComment; 231 | } 232 | 233 | /** 234 | * Returns the doc comment. 235 | * 236 | * @return string|null The doc comment. 237 | * 238 | * @api 239 | */ 240 | public function getDocComment() 241 | { 242 | return $this->docComment; 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/MondatorTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests; 13 | 14 | use Mandango\Mondator\Extension; 15 | use Mandango\Mondator\Mondator; 16 | use PHPUnit\Framework\TestCase; 17 | 18 | class MondatorTest extends TestCase 19 | { 20 | public function testConfigClasses() 21 | { 22 | $mondator = new Mondator(); 23 | $mondator->setConfigClass('Article', $article = array( 24 | 'title' => 'string', 25 | 'content' => 'string', 26 | )); 27 | $mondator->setConfigClass('Comment', $comment = array( 28 | 'name' => 'string', 29 | 'text' => 'string', 30 | )); 31 | 32 | $this->assertTrue($mondator->hasConfigClass('Article')); 33 | $this->assertFalse($mondator->hasConfigClass('Category')); 34 | 35 | $this->assertSame($article, $mondator->getConfigClass('Article')); 36 | $this->assertSame($comment, $mondator->getConfigClass('Comment')); 37 | 38 | $this->assertSame(array('Article' => $article, 'Comment' => $comment), $mondator->getConfigClasses()); 39 | 40 | $mondator->setConfigClasses($classes = array( 41 | 'Category' => array('name' => 'string'), 42 | 'Post' => array('message' => 'string'), 43 | )); 44 | $this->assertSame($classes, $mondator->getConfigClasses()); 45 | } 46 | 47 | public function testGetConfigClassNotExists() 48 | { 49 | $this->expectException(\InvalidArgumentException::class); 50 | $mondator = new Mondator(); 51 | $mondator->getConfigClass('Article'); 52 | } 53 | 54 | public function testExtensions() 55 | { 56 | $extension1 = new ExtensionTesting(array('required' => 'value')); 57 | $extension2 = new ExtensionTesting(array('required' => 'value')); 58 | $extension3 = new ExtensionTesting(array('required' => 'value')); 59 | $extension4 = new ExtensionTesting(array('required' => 'value')); 60 | 61 | $mondator = new Mondator(); 62 | 63 | $mondator->addExtension($extension1); 64 | $mondator->addExtension($extension2); 65 | $this->assertSame(array($extension1, $extension2), $mondator->getExtensions()); 66 | 67 | $mondator->setExtensions($extensions = array($extension3, $extension4)); 68 | $this->assertSame($extensions, $mondator->getExtensions()); 69 | } 70 | 71 | public function testGenerateContainers() 72 | { 73 | $mondator = new Mondator(); 74 | $mondator->setConfigClasses(array( 75 | 'Article' => array( 76 | 'name' => 'foo', 77 | ), 78 | 'Category' => array( 79 | 'name' => 'bar', 80 | ), 81 | )); 82 | $mondator->setExtensions(array( 83 | new \Mandango\Mondator\Tests\Fixtures\Extension\Name(), 84 | new \Mandango\Mondator\Tests\Fixtures\Extension\InitDefinition(array( 85 | 'definition_name' => 'myclass', 86 | 'class_name' => 'MiClase', 87 | )), 88 | new \Mandango\Mondator\Tests\Fixtures\Extension\AddProperty(array( 89 | 'definition' => 'myclass', 90 | 'visibility' => 'public', 91 | 'name' => 'MiPropiedad', 92 | 'value' => 'foobar', 93 | )), 94 | )); 95 | 96 | $containers = $mondator->generateContainers(); 97 | 98 | $this->assertSame(3, count($containers)); 99 | $this->assertTrue(isset($containers['_global'])); 100 | $this->assertTrue(isset($containers['Article'])); 101 | $this->assertTrue(isset($containers['Category'])); 102 | $this->assertInstanceOf('Mandango\Mondator\Container', $containers['Article']); 103 | $this->assertInstanceOf('Mandango\Mondator\Container', $containers['Category']); 104 | 105 | $definitions = $containers['Article']; 106 | $this->assertSame(2, count($definitions->getDefinitions())); 107 | $this->assertTrue(isset($definitions['name'])); 108 | $this->assertTrue(isset($definitions['myclass'])); 109 | $this->assertSame('foo', $definitions['name']->getClassName()); 110 | 111 | $definitions = $containers['Category']; 112 | $this->assertSame(2, count($definitions->getDefinitions())); 113 | $this->assertTrue(isset($definitions['name'])); 114 | $this->assertTrue(isset($definitions['myclass'])); 115 | $this->assertSame('bar', $definitions['name']->getClassName()); 116 | } 117 | 118 | public function testGenerateContainersNewConfigClasses() 119 | { 120 | $mondator = new Mondator(); 121 | $mondator->setConfigClasses(array( 122 | 'Article' => array( 123 | 'name' => 'MyArticle', 124 | 'extensions' => array( 125 | array( 126 | 'class' => 'Mandango\Mondator\Tests\Fixtures\Extension\NewConfigClass', 127 | 'options' => array( 128 | 'suffix' => 'Translation', 129 | 'name' => 'translation', 130 | 'multiple' => true, 131 | 'multiple_suffix' => 'Multiple', 132 | 'multiple_name' => 'multiplex', 133 | ), 134 | ), 135 | ), 136 | ), 137 | 'Category' => array( 138 | 'name' => 'MyCategory', 139 | ), 140 | )); 141 | $mondator->setExtensions(array( 142 | new \Mandango\Mondator\Tests\Fixtures\Extension\Name(), 143 | new \Mandango\Mondator\Tests\Fixtures\Extension\ProcessOthersFromArray(), 144 | )); 145 | 146 | $containers = $mondator->generateContainers(); 147 | 148 | $this->assertSame(5, count($containers)); 149 | $this->assertTrue(isset($containers['_global'])); 150 | $this->assertTrue(isset($containers['Article'])); 151 | $this->assertTrue(isset($containers['ArticleTranslation'])); 152 | $this->assertTrue(isset($containers['ArticleTranslationMultiple'])); 153 | $this->assertTrue(isset($containers['Category'])); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Dumper.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator; 13 | 14 | use Mandango\Mondator\Definition\Definition as BaseDefinition; 15 | 16 | /** 17 | * The Mondator Dumper. 18 | * 19 | * @author Pablo Díez 20 | * 21 | * @api 22 | */ 23 | class Dumper 24 | { 25 | private $definition; 26 | 27 | /** 28 | * Constructor. 29 | * 30 | * @param Mandango\Mondator\Definition\Definition $definition The definition. 31 | * 32 | * @api 33 | */ 34 | public function __construct(BaseDefinition $definition) 35 | { 36 | $this->setDefinition($definition); 37 | } 38 | 39 | /** 40 | * Set the definition. 41 | * 42 | * @param Mandango\Mondator\Definition\Definition $definition The definition. 43 | * 44 | * @api 45 | */ 46 | public function setDefinition(BaseDefinition $definition) 47 | { 48 | $this->definition = $definition; 49 | } 50 | 51 | /** 52 | * Returns the definition 53 | * 54 | * @return Mandango\Mondator\Definition\Definition The definition. 55 | * 56 | * @api 57 | */ 58 | public function getDefinition() 59 | { 60 | return $this->definition; 61 | } 62 | 63 | /** 64 | * Dump the definition. 65 | * 66 | * @return string The PHP code of the definition. 67 | * 68 | * @api 69 | */ 70 | public function dump() 71 | { 72 | return 73 | $this->startFile(). 74 | $this->addNamespace(). 75 | $this->startClass(). 76 | $this->addConstants(). 77 | $this->addProperties(). 78 | $this->addMethods(). 79 | $this->endClass() 80 | ; 81 | } 82 | 83 | /** 84 | * Export an array. 85 | * 86 | * Based on Symfony\Component\DependencyInjection\Dumper\PhpDumper::exportParameters 87 | * http://github.com/symfony/symfony 88 | * 89 | * @param array $array The array. 90 | * @param int $indent The indent. 91 | * 92 | * @return string The array exported. 93 | */ 94 | static public function exportArray(array $array, $indent) 95 | { 96 | $code = array(); 97 | foreach ($array as $key => $value) { 98 | if (is_array($value)) { 99 | $value = self::exportArray($value, $indent + 4); 100 | } else { 101 | $value = null === $value ? 'null' : var_export($value, true); 102 | } 103 | 104 | $code[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), var_export($key, true), $value); 105 | } 106 | 107 | return sprintf("array(\n%s\n%s)", implode("\n", $code), str_repeat(' ', $indent - 4)); 108 | } 109 | 110 | private function startFile() 111 | { 112 | return <<definition->getNamespace()) { 121 | return ''; 122 | } 123 | 124 | return <<definition->getDocComment()) { 137 | $code .= $docComment."\n"; 138 | } 139 | 140 | /* 141 | * declaration 142 | */ 143 | $declaration = ''; 144 | 145 | // abstract 146 | if ($this->definition->isAbstract()) { 147 | $declaration .= 'abstract '; 148 | } 149 | 150 | // class 151 | $declaration .= 'class '.$this->definition->getClassName(); 152 | 153 | // parent class 154 | if ($parentClass = $this->definition->getParentClass()) { 155 | $declaration .= ' extends '.$parentClass; 156 | } 157 | 158 | // interfaces 159 | if ($interfaces = $this->definition->getInterfaces()) { 160 | $declaration .= ' implements '.implode(', ', $interfaces); 161 | } 162 | 163 | $code .= <<definition->getConstants() as $constant) { 176 | $code = $code . "\n const {$constant->getName()} = {$constant->getValue()};"; 177 | } 178 | 179 | return "$code\n"; 180 | } 181 | 182 | private function addProperties() 183 | { 184 | $code = ''; 185 | 186 | $properties = $this->definition->getProperties(); 187 | foreach ($properties as $property) { 188 | $code .= "\n"; 189 | 190 | if ($docComment = $property->getDocComment()) { 191 | $code .= $docComment."\n"; 192 | } 193 | $isStatic = $property->isStatic() ? 'static ' : ''; 194 | 195 | $value = $property->getValue(); 196 | if (null === $value) { 197 | $code .= <<getVisibility()} \${$property->getName()}; 199 | EOF; 200 | } else { 201 | $value = is_array($property->getValue()) ? self::exportArray($property->getValue(), 8) : var_export($property->getValue(), true); 202 | 203 | $code .= <<getVisibility()} \${$property->getName()} = $value; 205 | EOF; 206 | } 207 | } 208 | if ($properties) { 209 | $code .= "\n"; 210 | } 211 | 212 | return $code; 213 | } 214 | 215 | private function addMethods() 216 | { 217 | $code = ''; 218 | 219 | foreach ($this->definition->getMethods() as $method) { 220 | $code .= "\n"; 221 | 222 | // doc comment 223 | if ($docComment = $method->getDocComment()) { 224 | $code .= $docComment."\n"; 225 | } 226 | 227 | // isFinal 228 | $isFinal = $method->isFinal() ? 'final ' : ''; 229 | 230 | // isStatic 231 | $isStatic = $method->isStatic() ? 'static ' : ''; 232 | 233 | // abstract 234 | if ($method->isAbstract()) { 235 | $code .= <<getVisibility()} function {$method->getName()}({$method->getArguments()}); 237 | EOF; 238 | } else { 239 | $methodCode = trim($method->getCode()); 240 | if ($methodCode) { 241 | $methodCode = ' '.$methodCode."\n "; 242 | } 243 | $code .= <<getVisibility()} function {$method->getName()}({$method->getArguments()}) 245 | { 246 | $methodCode} 247 | EOF; 248 | } 249 | 250 | $code .= "\n"; 251 | } 252 | 253 | return $code; 254 | } 255 | 256 | private function endClass() 257 | { 258 | $code = ''; 259 | 260 | if (!$this->definition->getProperties() && !$this->definition->getMethods()) { 261 | $code .= "\n"; 262 | } 263 | 264 | $code .= << 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests; 13 | 14 | use Mandango\Mondator\Mondator; 15 | use Mandango\Mondator\Extension; 16 | use PHPUnit\Framework\TestCase; 17 | 18 | class ExtensionTesting extends Extension 19 | { 20 | protected function setUp() 21 | { 22 | $this->addRequiredOptions(array( 23 | 'required', 24 | )); 25 | 26 | $this->addOptions(array( 27 | 'optional' => 'default_value', 28 | 'foo' => null, 29 | 'bar' => null, 30 | )); 31 | } 32 | 33 | protected function doClassProcess() 34 | { 35 | } 36 | } 37 | 38 | class ExtensionTest extends TestCase 39 | { 40 | public function testConstructorOptions() 41 | { 42 | $extension = new ExtensionTesting(array('required' => 'value')); 43 | $this->assertSame(array( 44 | 'required' => 'value', 45 | 'optional' => 'default_value', 46 | 'foo' => null, 47 | 'bar' => null, 48 | ), $extension->getOptions()); 49 | 50 | $extension = new ExtensionTesting(array('required' => 'barfoo', 'foo' => 'foobar')); 51 | $this->assertSame(array( 52 | 'required' => 'barfoo', 53 | 'optional' => 'default_value', 54 | 'foo' => 'foobar', 55 | 'bar' => null, 56 | ), $extension->getOptions()); 57 | } 58 | 59 | public function testConstructorOptionNotExists() 60 | { 61 | $this->expectException(\InvalidArgumentException::class); 62 | new ExtensionTesting(array('foobar' => 'barfoo')); 63 | } 64 | 65 | public function testConstructorNotSomeRequiredOption() 66 | { 67 | $this->expectException(\RuntimeException::class); 68 | new ExtensionTesting(array('foo' => 'bar')); 69 | } 70 | 71 | public function testHasOption() 72 | { 73 | $extension = new ExtensionTesting(array('required' => 'value')); 74 | $this->assertTrue($extension->hasOption('foo')); 75 | $this->assertFalse($extension->hasOption('foobar')); 76 | } 77 | 78 | public function testSetOption() 79 | { 80 | $extension = new ExtensionTesting(array('required' => 'value')); 81 | $extension->setOption('foo', 'barfoo'); 82 | $this->assertSame('barfoo', $extension->getOption('foo')); 83 | $this->assertSame('value', $extension->getOption('required')); 84 | $this->assertSame('default_value', $extension->getOption('optional')); 85 | } 86 | 87 | public function testSetOptionNotExists() 88 | { 89 | $this->expectException(\InvalidArgumentException::class); 90 | $extension = new ExtensionTesting(array('required' => 'value')); 91 | $extension->setOption('foobar', 'barfoo'); 92 | } 93 | 94 | public function testGetOptions() 95 | { 96 | $extension = new ExtensionTesting(array('required' => 'value')); 97 | $this->assertSame(array( 98 | 'required' => 'value', 99 | 'optional' => 'default_value', 100 | 'foo' => null, 101 | 'bar' => null, 102 | ), $extension->getOptions()); 103 | } 104 | 105 | public function testGetOption() 106 | { 107 | $extension = new ExtensionTesting(array('required' => 'value')); 108 | $this->assertSame('value', $extension->getOption('required')); 109 | $this->assertSame('default_value', $extension->getOption('optional')); 110 | $this->assertNull($extension->getOption('bar')); 111 | } 112 | 113 | public function testGetOptionNotExists() 114 | { 115 | $this->expectException(\InvalidArgumentException::class); 116 | $extension = new ExtensionTesting(array('required' => 'value')); 117 | $extension->getOption('foobar'); 118 | } 119 | 120 | public function testTwigSupport() 121 | { 122 | $mondator = new Mondator(); 123 | $mondator->setConfigClasses(array( 124 | 'Model\Article' => array( 125 | 'fields' => array( 126 | 'title' => array(), 127 | 'content' => array(), 128 | ), 129 | ), 130 | )); 131 | $mondator->addExtension(new \Mandango\Mondator\Tests\Fixtures\Extension\Twig\MandangoTestsTwigExtension()); 132 | 133 | $containers = $mondator->generateContainers(); 134 | $article = $containers['Model\Article']->getDefinition('document'); 135 | 136 | // properties 137 | $this->assertTrue($article->hasPropertyByName('publicProperty')); 138 | $this->assertSame('public', $article->getPropertyByName('publicProperty')->getVisibility()); 139 | 140 | $this->assertTrue($article->hasPropertyByName('protectedProperty')); 141 | $this->assertSame('protected', $article->getPropertyByName('protectedProperty')->getVisibility()); 142 | 143 | $this->assertTrue($article->hasPropertyByName('privateProperty')); 144 | $this->assertSame('private', $article->getPropertyByName('privateProperty')->getVisibility()); 145 | 146 | $this->assertTrue($article->hasPropertyByName('staticProperty')); 147 | $this->assertTrue($article->getPropertyByName('staticProperty')->isStatic()); 148 | 149 | $this->assertTrue($article->hasPropertyByName('anotherPublicProperty')); 150 | $this->assertSame('public', $article->getPropertyByName('anotherPublicProperty')->getVisibility()); 151 | 152 | $this->assertTrue($article->hasPropertyByName('anotherProtectedProperty')); 153 | $this->assertSame('protected', $article->getPropertyByName('anotherProtectedProperty')->getVisibility()); 154 | 155 | $this->assertTrue($article->hasPropertyByName('anotherPrivateProperty')); 156 | $this->assertSame('private', $article->getPropertyByName('anotherPrivateProperty')->getVisibility()); 157 | 158 | // methods 159 | $this->assertTrue($article->hasMethodByName('publicMethod')); 160 | $this->assertSame('public', $article->getMethodbyName('publicMethod')->getVisibility()); 161 | 162 | $this->assertTrue($article->hasMethodByName('protectedMethod')); 163 | $this->assertSame('protected', $article->getMethodbyName('protectedMethod')->getVisibility()); 164 | 165 | $this->assertTrue($article->hasMethodByName('privateMethod')); 166 | $this->assertSame('private', $article->getMethodbyName('privateMethod')->getVisibility()); 167 | 168 | $this->assertTrue($article->hasMethodByName('methodWithPhpDoc')); 169 | $this->assertSame(<<getMethodbyName('methodWithPhpDoc')->getDocComment()); 175 | 176 | $this->assertTrue($article->hasMethodByName('methodWithArguments')); 177 | $this->assertSame('$name, $value', $article->getMethodbyName('methodWithArguments')->getArguments()); 178 | 179 | $this->assertTrue($article->hasMethodByName('methodWithCode')); 180 | $this->assertTrue($article->hasMethodByName('methodWithCode')); 181 | $this->assertSame(<<getMethodbyName('methodWithCode')->getCode()); 185 | 186 | $this->assertTrue($article->hasMethodByName('staticMethod')); 187 | $this->assertTrue($article->getMethodByName('staticMethod')->isStatic()); 188 | 189 | $this->assertTrue($article->hasMethodByName('methodWithObjectProperties')); 190 | $this->assertSame('\ArrayObject $array, \Mandango\Query $query', $article->getMethodbyName('methodWithObjectProperties')->getArguments()); 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Mondator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator; 13 | 14 | /** 15 | * Mondator. 16 | * 17 | * @author Pablo Díez 18 | * 19 | * @api 20 | */ 21 | class Mondator 22 | { 23 | private $configClasses; 24 | private $extensions; 25 | 26 | /** 27 | * Constructor. 28 | * 29 | * @api 30 | */ 31 | public function __construct() 32 | { 33 | $this->configClasses = []; 34 | $this->extensions = []; 35 | } 36 | 37 | /** 38 | * Set a config class. 39 | * 40 | * @param string $class The class. 41 | * @param array $configClass The config class. 42 | * 43 | * @api 44 | */ 45 | public function setConfigClass($class, array $configClass) 46 | { 47 | $this->configClasses[$class] = $configClass; 48 | } 49 | 50 | /** 51 | * Set the config classes. 52 | * 53 | * @param array $configClasses An array of config classes (class as key and config class as value). 54 | * 55 | * @api 56 | */ 57 | public function setConfigClasses(array $configClasses) 58 | { 59 | $this->configClasses = array(); 60 | foreach ($configClasses as $class => $configClass) { 61 | $this->setConfigClass($class, $configClass); 62 | } 63 | } 64 | 65 | /** 66 | * Returns if a config class exists. 67 | * 68 | * @param string $class The class. 69 | * 70 | * @return bool Returns if the config class exists. 71 | * 72 | * @api 73 | */ 74 | public function hasConfigClass($class) 75 | { 76 | return array_key_exists($class, $this->configClasses); 77 | } 78 | 79 | /** 80 | * Returns the config classes. 81 | * 82 | * @return array The config classes. 83 | * 84 | * @api 85 | */ 86 | public function getConfigClasses() 87 | { 88 | return $this->configClasses; 89 | } 90 | 91 | /** 92 | * Returns a config class. 93 | * 94 | * @param string $class The class. 95 | * 96 | * @return array The config class. 97 | * 98 | * @throws \InvalidArgumentException If the config class does not exists. 99 | * 100 | * @api 101 | */ 102 | public function getConfigClass($class) 103 | { 104 | if (!$this->hasConfigClass($class)) { 105 | throw new \InvalidArgumentException(sprintf('The config class "%s" does not exists.', $class)); 106 | } 107 | 108 | return $this->configClasses[$class]; 109 | } 110 | 111 | /** 112 | * Add a extension. 113 | * 114 | * @param Mandango\Mondator\Extension $extension The extension. 115 | * 116 | * @api 117 | */ 118 | public function addExtension(Extension $extension) 119 | { 120 | $this->extensions[] = $extension; 121 | } 122 | 123 | /** 124 | * Set the extensions. 125 | * 126 | * @param array $extensions An array of extensions. 127 | * 128 | * @api 129 | */ 130 | public function setExtensions(array $extensions) 131 | { 132 | $this->extensions = array(); 133 | foreach ($extensions as $extension) { 134 | $this->addExtension($extension); 135 | } 136 | } 137 | 138 | /** 139 | * Returns the extensions. 140 | * 141 | * @return array The extensions. 142 | * 143 | * @api 144 | */ 145 | public function getExtensions() 146 | { 147 | return $this->extensions; 148 | } 149 | 150 | /** 151 | * Generate the containers. 152 | * 153 | * @return array The containers. 154 | * 155 | * @api 156 | */ 157 | public function generateContainers() 158 | { 159 | $containers = array(); 160 | $containers['_global'] = new Container(); 161 | 162 | // global extensions 163 | $globalExtensions = $this->getExtensions(); 164 | 165 | // configClasses 166 | $configClasses = new \ArrayObject(); 167 | foreach ($this->getConfigClasses() as $class => $configClass) { 168 | $configClasses[$class] = new \ArrayObject($configClass); 169 | } 170 | 171 | // classes extensions 172 | $classesExtensions = new \ArrayObject(); 173 | $this->generateContainersClassesExtensions($globalExtensions, $classesExtensions, $configClasses); 174 | 175 | // config class process 176 | foreach ($classesExtensions as $class => $classExtensions) { 177 | foreach ($classExtensions as $classExtension) { 178 | $classExtension->configClassProcess($class, $configClasses); 179 | } 180 | } 181 | 182 | // pre global process 183 | foreach ($globalExtensions as $globalExtension) { 184 | $globalExtension->preGlobalProcess($configClasses, $containers['_global']); 185 | } 186 | 187 | // class process 188 | foreach ($classesExtensions as $class => $classExtensions) { 189 | $containers[$class] = $container = new Container(); 190 | foreach ($classExtensions as $classExtension) { 191 | $classExtension->classProcess($class, $configClasses, $container); 192 | } 193 | } 194 | 195 | // post global process 196 | foreach ($globalExtensions as $globalExtension) { 197 | $globalExtension->postGlobalProcess($configClasses, $containers['_global']); 198 | } 199 | 200 | return $containers; 201 | } 202 | 203 | private function generateContainersClassesExtensions($globalExtensions, $classesExtensions, $configClasses) 204 | { 205 | foreach ($configClasses as $class => $configClass) { 206 | if (isset($classesExtensions[$class])) { 207 | continue; 208 | } 209 | 210 | $classesExtensions[$class] = $classExtensions = new \ArrayObject($globalExtensions); 211 | $this->generateContainersNewClassExtensions($class, $classExtensions, $configClasses); 212 | 213 | foreach ($classExtensions as $classExtension) { 214 | $newConfigClasses = new \ArrayObject(); 215 | $classExtension->newConfigClassesProcess($class, $configClasses, $newConfigClasses); 216 | 217 | foreach ($newConfigClasses as $newClass => $newConfigClass) { 218 | $configClasses[$newClass] = new \ArrayObject($newConfigClass); 219 | } 220 | 221 | $this->generateContainersClassesExtensions($globalExtensions, $classesExtensions, $configClasses); 222 | } 223 | } 224 | } 225 | 226 | private function generateContainersNewClassExtensions($class, $classExtensions, $configClasses, $extensions = null) 227 | { 228 | if (null === $extensions) { 229 | $extensions = $classExtensions; 230 | } 231 | 232 | foreach ($extensions as $extension) { 233 | $newClassExtensions = new \ArrayObject(); 234 | $extension->newClassExtensionsProcess($class, $configClasses, $newClassExtensions); 235 | 236 | foreach ($newClassExtensions as $newClassExtension) { 237 | if (!$newClassExtension instanceof ClassExtension) { 238 | throw new \RuntimeException(sprintf('Some class extension of the class "%s" in the extension "%s" is not an instance of ClassExtension.', $class, get_class($extension))); 239 | } 240 | if ($newClassExtension instanceof Extension) { 241 | throw new \RuntimeException(sprintf('Some class extension of the class "%s" in the extension "%s" is a instance of Extension, and it can be only a instance of ClassExtension.', $class, get_class($extension))); 242 | } 243 | 244 | $classExtensions[] = $newClassExtension; 245 | $this->generateContainersNewClassExtensions($class, $classExtensions, $configClasses, $newClassExtension); 246 | } 247 | } 248 | } 249 | 250 | /** 251 | * Dump containers. 252 | * 253 | * @param array $containers An array of containers. 254 | * 255 | * @api 256 | */ 257 | public function dumpContainers(array $containers) 258 | { 259 | 260 | // output 261 | foreach ($containers as $container) { 262 | foreach ($container->getDefinitions() as $name => $definition) { 263 | $output = $definition->getOutput($name); 264 | $dir = $output->getDir(); 265 | 266 | 267 | $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', '/', $definition->getClass()).'.php'; 268 | $path = dirname($file); 269 | 270 | if (!file_exists($path) && false === @mkdir($path, 0777, true)) { 271 | throw new \RuntimeException(sprintf('Unable to create the %s directory.', $path)); 272 | } 273 | 274 | if (!is_writable($path)) { 275 | throw new \RuntimeException(sprintf('Unable to write in the %s directory.', $path)); 276 | } 277 | 278 | if (!file_exists($file) || $output->getOverride()) { 279 | $dumper = new Dumper($definition); 280 | $content = $dumper->dump(); 281 | 282 | $tmpFile = tempnam(dirname($file), basename($file)); 283 | if (false === @file_put_contents($tmpFile, $content) || !@rename($tmpFile, $file)) { 284 | throw new \RuntimeException(sprintf('Failed to write the file "%s".', $file)); 285 | } 286 | @chmod($file, 0666 & ~umask()); 287 | } 288 | } 289 | } 290 | } 291 | 292 | /** 293 | * Generate and dump the containers. 294 | * 295 | * @api 296 | */ 297 | public function process() 298 | { 299 | $this->dumpContainers($this->generateContainers()); 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /tests/Mandango/Mondator/Tests/Definition/DefinitionTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Tests\Definition; 13 | 14 | use Mandango\Mondator\Definition\Constant; 15 | use Mandango\Mondator\Definition\Definition; 16 | use Mandango\Mondator\Definition\Method; 17 | use Mandango\Mondator\Definition\Property; 18 | use PHPUnit\Framework\TestCase; 19 | 20 | class DefinitionTest extends TestCase 21 | { 22 | public function testConstructor() 23 | { 24 | $definition = new Definition('Namespace\\Class1'); 25 | $this->assertSame('Namespace\\Class1', $definition->getClass()); 26 | } 27 | 28 | public function testClass() 29 | { 30 | $definition = new Definition('Namespace\\Class1'); 31 | $this->assertSame('Namespace\\Class1', $definition->getClass()); 32 | $definition->setClass('My\\Other\\Namespace\\MyOtherClass'); 33 | $this->assertSame('My\\Other\\Namespace\\MyOtherClass', $definition->getClass()); 34 | } 35 | 36 | public function testNamespace() 37 | { 38 | $definition = new Definition('Namespace\\Class1'); 39 | $this->assertSame('Namespace', $definition->getNamespace()); 40 | } 41 | 42 | public function testClassName() 43 | { 44 | $definition = new Definition('Namespace\\Class1'); 45 | $this->assertSame('Class1', $definition->getClassName()); 46 | } 47 | 48 | public function testParentClass() 49 | { 50 | $definition = new Definition('Class1'); 51 | $definition->setParentClass('ParentFooBar'); 52 | $this->assertSame('ParentFooBar', $definition->getParentClass()); 53 | } 54 | 55 | public function testInterfaces() 56 | { 57 | $definition = new Definition('Class1'); 58 | $definition->addInterface('\ArrayAccess'); 59 | $definition->addInterface('\Countable'); 60 | $this->assertSame(array('\ArrayAccess', '\Countable'), $definition->getInterfaces()); 61 | 62 | $definition->setInterfaces($interfaces = array('\ArrayObject', '\InfiniteIterador')); 63 | $this->assertSame($interfaces, $definition->getInterfaces()); 64 | } 65 | 66 | public function testFinal() 67 | { 68 | $definition = new Definition('Class1'); 69 | $this->assertFalse($definition->isFinal()); 70 | $definition->setFinal(true); 71 | $this->assertTrue($definition->isFinal()); 72 | } 73 | 74 | public function testAbstract() 75 | { 76 | $definition = new Definition('Class1'); 77 | $this->assertFalse($definition->isAbstract()); 78 | $definition->setAbstract(true); 79 | $this->assertTrue($definition->isAbstract()); 80 | } 81 | 82 | public function testProperties() 83 | { 84 | $properties = array(); 85 | 86 | $properties[1] = new Property('public', 'property1', true); 87 | $properties[2] = new Property('public', 'property2', true); 88 | $properties[3] = new Property('public', 'property3', true); 89 | $properties[4] = new Property('public', 'property4', true); 90 | 91 | $definition = new Definition('Class1'); 92 | 93 | // addProperty 94 | $definition->addProperty($properties[1]); 95 | $definition->addProperty($properties[2]); 96 | $this->assertSame(array($properties[1], $properties[2]), $definition->getProperties()); 97 | 98 | // setProperties 99 | $definition->setProperties(array($properties[3], $properties[4])); 100 | $this->assertSame(array($properties[3], $properties[4]), $definition->getProperties()); 101 | 102 | // hasPropertyByName 103 | $this->assertTrue($definition->hasPropertyByName('property3')); 104 | $this->assertFalse($definition->hasPropertyByName('property1')); 105 | 106 | // getPropertyByName 107 | $this->assertSame($properties[3], $definition->getPropertyByName('property3')); 108 | $this->assertSame($properties[4], $definition->getPropertyByName('property4')); 109 | 110 | // removePropertyByName 111 | $definition->setProperties($properties); 112 | $definition->removePropertyByName('property2'); 113 | $this->assertFalse($definition->hasPropertyByName('property2')); 114 | $this->assertTrue($definition->hasPropertyByName('property1')); 115 | $this->assertTrue($definition->hasPropertyByName('property3')); 116 | $this->assertTrue($definition->hasPropertyByName('property4')); 117 | } 118 | 119 | public function testGetPropertyByNameNotExists() 120 | { 121 | $this->expectException(\InvalidArgumentException::class); 122 | $definition = new Definition('Class1'); 123 | $definition->getPropertyByName('propertyName'); 124 | } 125 | 126 | public function testRemovePropertyByNameNotExists() 127 | { 128 | $this->expectException(\InvalidArgumentException::class); 129 | $definition = new Definition('Class1'); 130 | $definition->removePropertyByName('propertyName'); 131 | } 132 | 133 | public function testMethods() 134 | { 135 | $methods = array(); 136 | 137 | $methods[1] = new Method('public', 'method1', '', ''); 138 | $methods[2] = new Method('public', 'method2', '', ''); 139 | $methods[3] = new Method('public', 'method3', '', ''); 140 | $methods[4] = new Method('public', 'method4', '', ''); 141 | 142 | $definition = new Definition('Class1'); 143 | 144 | // addMethod 145 | $definition->addMethod($methods[1]); 146 | $definition->addMethod($methods[2]); 147 | $this->assertSame(array($methods[1], $methods[2]), $definition->getMethods()); 148 | 149 | // setMethods 150 | $definition->setMethods(array($methods[3], $methods[4])); 151 | $this->assertSame(array($methods[3], $methods[4]), $definition->getMethods()); 152 | 153 | // hasMethodByName 154 | $this->assertTrue($definition->hasMethodByName('method3')); 155 | $this->assertFalse($definition->hasMethodByName('method1')); 156 | 157 | // getMethodByName 158 | $this->assertSame($methods[3], $definition->getMethodByName('method3')); 159 | $this->assertSame($methods[4], $definition->getMethodByName('method4')); 160 | 161 | // removeMethodByName 162 | $definition->setMethods($methods); 163 | $definition->removeMethodByName('method2'); 164 | $this->assertFalse($definition->hasMethodByName('method2')); 165 | $this->assertTrue($definition->hasMethodByName('method1')); 166 | $this->assertTrue($definition->hasMethodByName('method3')); 167 | $this->assertTrue($definition->hasMethodByName('method4')); 168 | } 169 | 170 | public function testGetMethodByNameNotExists() 171 | { 172 | $this->expectException(\InvalidArgumentException::class); 173 | $definition = new Definition('Class1'); 174 | $definition->getMethodByName('methodName'); 175 | } 176 | 177 | public function testRemoveMethodByNameNotExists() 178 | { 179 | $this->expectException(\InvalidArgumentException::class); 180 | $definition = new Definition('Class1'); 181 | $definition->removeMethodByName('methodName'); 182 | } 183 | 184 | public function testDocComment() 185 | { 186 | $definition = new Definition('Class1'); 187 | $definition->setDocComment('myDoc'); 188 | $this->assertSame('myDoc', $definition->getDocComment()); 189 | } 190 | 191 | public function testAddConstant() 192 | { 193 | $definition = new Definition('Class1'); 194 | $constant = new Constant('X', 'Y'); 195 | 196 | $definition->addConstant($constant); 197 | $constants = $definition->getConstants(); 198 | 199 | $this->assertContains($constant, $constants); 200 | $this->assertEquals(sizeof($constants), 1); 201 | } 202 | 203 | public function testSetConstants() 204 | { 205 | $definition = new Definition('Class1'); 206 | $constants = array(new Constant('X', 'Y'), new Constant('Z', 'W')); 207 | 208 | $definition->setConstants($constants); 209 | 210 | $this->assertEquals($definition->getConstants(), $constants); 211 | } 212 | 213 | public function testHasConstantByNameShouldBeTrue() 214 | { 215 | $definition = new Definition('Class1'); 216 | $constant = new Constant('X', 'Y'); 217 | 218 | $definition->addConstant($constant); 219 | 220 | $this->assertTrue($definition->hasConstantByName('X')); 221 | } 222 | 223 | public function testHasConstantByNameShouldBeFalse() 224 | { 225 | $definition = new Definition('Class1'); 226 | 227 | $this->assertFalse($definition->hasConstantByName('X')); 228 | } 229 | 230 | public function testGetConstantByName() 231 | { 232 | $definition = new Definition('Class1'); 233 | $constant = new Constant('X', 'Y'); 234 | 235 | $definition->addConstant($constant); 236 | 237 | $this->assertEquals($definition->getConstantByName('X'), $constant); 238 | } 239 | 240 | public function testGetConstantByNameShouldThrowException() 241 | { 242 | $this->expectException(\InvalidArgumentException::class); 243 | $definition = new Definition('Class1'); 244 | 245 | $definition->getConstantByName('X'); 246 | } 247 | 248 | public function testRemoveConstantByname() 249 | { 250 | $definition = new Definition('Class1'); 251 | $constant = new Constant('X', 'Y'); 252 | 253 | $definition->addConstant($constant); 254 | $definition->removeConstantByName('X'); 255 | 256 | $this->assertTrue(sizeof($definition->getConstants()) === 0); 257 | } 258 | 259 | public function testRemoveConstantBynameShouldThrowException() 260 | { 261 | $this->expectException(\InvalidArgumentException::class); 262 | $definition = new Definition('Class1'); 263 | 264 | $definition->removeConstantByName('X'); 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/Definition/Definition.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator\Definition; 13 | 14 | /** 15 | * Represents a definition of a class. 16 | * 17 | * @author Pablo Díez 18 | * 19 | * @api 20 | */ 21 | class Definition 22 | { 23 | private $class; 24 | private $parentClass; 25 | private $interfaces; 26 | private $final; 27 | private $abstract; 28 | private $constants; 29 | private $properties; 30 | private $methods; 31 | private $docComment; 32 | 33 | /** 34 | * Constructor. 35 | * 36 | * @param string $class The class. 37 | * 38 | * @api 39 | */ 40 | public function __construct($class) 41 | { 42 | $this->setClass($class); 43 | $this->interfaces = array(); 44 | $this->final = false; 45 | $this->abstract = false; 46 | $this->constants = array(); 47 | $this->properties = array(); 48 | $this->methods = array(); 49 | } 50 | 51 | /** 52 | * Set the class. 53 | * 54 | * @param string $class The class. 55 | * 56 | * @api 57 | */ 58 | public function setClass($class) 59 | { 60 | $this->class = $class; 61 | } 62 | 63 | /** 64 | * Returns the class. 65 | * 66 | * @return string The class. 67 | * 68 | * @api 69 | */ 70 | public function getClass() 71 | { 72 | return $this->class; 73 | } 74 | 75 | /** 76 | * Returns the namespace. 77 | * 78 | * @return string|null The namespace. 79 | * 80 | * @api 81 | */ 82 | public function getNamespace() 83 | { 84 | if (false !== $pos = strrpos($this->class, '\\')) { 85 | return substr($this->class, 0, $pos); 86 | } 87 | 88 | return null; 89 | } 90 | 91 | /** 92 | * Returns the class name. 93 | * 94 | * @return string|null The class name. 95 | * 96 | * @api 97 | */ 98 | public function getClassName() 99 | { 100 | if (false !== $pos = strrpos($this->class, '\\')) { 101 | return substr($this->class, $pos + 1); 102 | } 103 | 104 | return $this->class; 105 | } 106 | 107 | /** 108 | * Set the parent class. 109 | * 110 | * @param string $parentClass The parent class. 111 | * 112 | * @api 113 | */ 114 | public function setParentClass($parentClass) 115 | { 116 | $this->parentClass = $parentClass; 117 | } 118 | 119 | /** 120 | * Returns the parent class. 121 | * 122 | * @return string The parent class. 123 | * 124 | * @api 125 | */ 126 | public function getParentClass() 127 | { 128 | return $this->parentClass; 129 | } 130 | 131 | /** 132 | * Add an interface. 133 | * 134 | * @param string $interface The interface. 135 | * 136 | * @api 137 | */ 138 | public function addInterface($interface) 139 | { 140 | $this->interfaces[] = $interface; 141 | } 142 | 143 | /** 144 | * Set the interfaces. 145 | * 146 | * @param array $interfaces The interfaces. 147 | * 148 | * @api 149 | */ 150 | public function setInterfaces(array $interfaces) 151 | { 152 | $this->interfaces = array(); 153 | foreach ($interfaces as $interface) { 154 | $this->addInterface($interface); 155 | } 156 | } 157 | 158 | /** 159 | * Returns the interfaces. 160 | * 161 | * @return array The interfaces. 162 | * 163 | * @api 164 | */ 165 | public function getInterfaces() 166 | { 167 | return $this->interfaces; 168 | } 169 | 170 | /** 171 | * Set if the class is final. 172 | * 173 | * @param bool $final If the class is final. 174 | * 175 | * @api 176 | */ 177 | public function setFinal($final) 178 | { 179 | $this->final = (bool) $final; 180 | } 181 | 182 | /** 183 | * Returns if the class is final. 184 | * 185 | * @return bool Returns if the class is final. 186 | * 187 | * @api 188 | */ 189 | public function isFinal() 190 | { 191 | return $this->final; 192 | } 193 | 194 | /** 195 | * Set if the class is abstract. 196 | * 197 | * @param bool $abstract If the class is abstract. 198 | * 199 | * @api 200 | */ 201 | public function setAbstract($abstract) 202 | { 203 | $this->abstract = (bool) $abstract; 204 | } 205 | 206 | /** 207 | * Returns if the class is abstract. 208 | * 209 | * @return bool If the class is abstract. 210 | * 211 | * @api 212 | */ 213 | public function isAbstract() 214 | { 215 | return $this->abstract; 216 | } 217 | 218 | /** 219 | * Add a constant. 220 | * 221 | * @param Mandango\Mondator\Definition\Constant $constant The constant. 222 | * 223 | * @api 224 | */ 225 | public function addConstant(Constant $constant) 226 | { 227 | $this->constants[] = $constant; 228 | } 229 | 230 | /** 231 | * Set the constants. 232 | * 233 | * @param array $constants An array of constants. 234 | * 235 | * @api 236 | */ 237 | public function setConstants(array $constants) 238 | { 239 | $this->constants = array(); 240 | foreach ($constants as $constant) { 241 | $this->addConstant($constant); 242 | } 243 | } 244 | 245 | /** 246 | * Returns the constants. 247 | * 248 | * @return array The constants. 249 | * 250 | * @api 251 | */ 252 | public function getConstants() 253 | { 254 | return $this->constants; 255 | } 256 | 257 | /** 258 | * Returns if a constant exists by name. 259 | * 260 | * @param string $name The constant name. 261 | * 262 | * @return bool If the constant exists. 263 | * 264 | * @api 265 | */ 266 | public function hasConstantByName($name) 267 | { 268 | foreach ($this->constants as $constant) { 269 | if ($constant->getName() == $name) { 270 | return true; 271 | } 272 | } 273 | 274 | return false; 275 | } 276 | 277 | /** 278 | * Returns a constant by name. 279 | * 280 | * @param string $name The constant name. 281 | * 282 | * @return Mandango\Mondator\Definition\Constant The constant. 283 | * 284 | * @throws \InvalidArgumentException If the constant does not exists. 285 | * 286 | * @api 287 | */ 288 | public function getConstantByName($name) 289 | { 290 | foreach ($this->constants as $constant) { 291 | if ($constant->getName() == $name) { 292 | return $constant; 293 | } 294 | } 295 | 296 | throw new \InvalidArgumentException(sprintf('The constant "%s" does not exists.', $name)); 297 | } 298 | 299 | /** 300 | * Remove property by name. 301 | * 302 | * @param string $name The constant name. 303 | * 304 | * @throws \InvalidArgumentException If the property does not exists. 305 | * 306 | * @api 307 | */ 308 | public function removeConstantByName($name) 309 | { 310 | foreach ($this->constants as $key => $constant) { 311 | if ($constant->getName() == $name) { 312 | unset($this->constants[$key]); 313 | return; 314 | } 315 | } 316 | 317 | throw new \InvalidArgumentException(sprintf('The constant "%s" does not exists.', $name)); 318 | } 319 | 320 | /** 321 | * Add a property. 322 | * 323 | * @param Mandango\Mondator\Definition\Property $property The property. 324 | * 325 | * @api 326 | */ 327 | public function addProperty(Property $property) 328 | { 329 | $this->properties[] = $property; 330 | } 331 | 332 | /** 333 | * Set the properties. 334 | * 335 | * @param array $properties An array of properties. 336 | * 337 | * @api 338 | */ 339 | public function setProperties(array $properties) 340 | { 341 | $this->properties = array(); 342 | foreach ($properties as $name => $property) { 343 | $this->addProperty($property); 344 | } 345 | } 346 | 347 | /** 348 | * Returns the properties. 349 | * 350 | * @return array The properties. 351 | * 352 | * @api 353 | */ 354 | public function getProperties() 355 | { 356 | return $this->properties; 357 | } 358 | 359 | /** 360 | * Returns if a property exists by name. 361 | * 362 | * @param string $name The property name. 363 | * 364 | * @return bool If the property exists. 365 | * 366 | * @api 367 | */ 368 | public function hasPropertyByName($name) 369 | { 370 | foreach ($this->properties as $property) { 371 | if ($property->getName() == $name) { 372 | return true; 373 | } 374 | } 375 | 376 | return false; 377 | } 378 | 379 | /** 380 | * Returns a property by name. 381 | * 382 | * @param string $name The property name. 383 | * 384 | * @return Mandango\Mondator\Definition\Property The property. 385 | * 386 | * @throws \InvalidArgumentException If the property does not exists. 387 | * 388 | * @api 389 | */ 390 | public function getPropertyByName($name) 391 | { 392 | foreach ($this->properties as $property) { 393 | if ($property->getName() == $name) { 394 | return $property; 395 | } 396 | } 397 | 398 | throw new \InvalidArgumentException(sprintf('The property "%s" does not exists.', $name)); 399 | } 400 | 401 | /** 402 | * Remove property by name. 403 | * 404 | * @param string $name The property name. 405 | * 406 | * @throws \InvalidArgumentException If the property does not exists. 407 | * 408 | * @api 409 | */ 410 | public function removePropertyByName($name) 411 | { 412 | foreach ($this->properties as $key => $property) { 413 | if ($property->getName() == $name) { 414 | unset($this->properties[$key]); 415 | return; 416 | } 417 | } 418 | 419 | throw new \InvalidArgumentException(sprintf('The property "%s" does not exists.', $name)); 420 | } 421 | 422 | /** 423 | * Add a method. 424 | * 425 | * @param Mandango\Mondator\Definition\Method $method The method. 426 | * 427 | * @api 428 | */ 429 | public function addMethod(Method $method) 430 | { 431 | $this->methods[] = $method; 432 | } 433 | 434 | /** 435 | * Set the methods. 436 | * 437 | * @param array $methods An array of methods. 438 | * 439 | * @api 440 | */ 441 | public function setMethods(array $methods) 442 | { 443 | $this->methods = array(); 444 | foreach ($methods as $name => $method) { 445 | $this->addMethod($method); 446 | } 447 | } 448 | 449 | /** 450 | * Returns the methods. 451 | * 452 | * @return array The methods. 453 | * 454 | * @api 455 | */ 456 | public function getMethods() 457 | { 458 | return $this->methods; 459 | } 460 | 461 | /** 462 | * Returns if exists a method by name. 463 | * 464 | * @param string $name The method name. 465 | * 466 | * @return bool If the method exists. 467 | * 468 | * @api 469 | */ 470 | public function hasMethodByName($name) 471 | { 472 | foreach ($this->methods as $method) { 473 | if ($method->getName() == $name) { 474 | return true; 475 | } 476 | } 477 | 478 | return false; 479 | } 480 | 481 | /** 482 | * Return a method by name. 483 | * 484 | * @param string $name The method name. 485 | * 486 | * @return Mandango\Mondator\Definition\Method The method. 487 | * 488 | * @throws \InvalidArgumentException If the method does not exists. 489 | * 490 | * @api 491 | */ 492 | public function getMethodByName($name) 493 | { 494 | foreach ($this->methods as $method) { 495 | if ($method->getName() == $name) { 496 | return $method; 497 | } 498 | } 499 | 500 | throw new \InvalidArgumentException(sprintf('The method "%s" does not exists.', $name)); 501 | } 502 | 503 | /** 504 | * Remove a method by name. 505 | * 506 | * @param string $name The method name. 507 | * 508 | * @throws \InvalidArgumentException If the method does not exists. 509 | * 510 | * @api 511 | */ 512 | public function removeMethodByName($name) 513 | { 514 | foreach ($this->methods as $key => $method) { 515 | if ($method->getName() == $name) { 516 | unset($this->methods[$key]); 517 | return; 518 | } 519 | } 520 | 521 | throw new \InvalidArgumentException(sprintf('The method "%s" does not exists.', $name)); 522 | } 523 | 524 | /** 525 | * Set the doc comment. 526 | * 527 | * @param string|null $docComment The doc comment. 528 | * 529 | * @api 530 | */ 531 | public function setDocComment($docComment) 532 | { 533 | $this->docComment = $docComment; 534 | } 535 | 536 | /** 537 | * Returns the doc comment. 538 | * 539 | * @return string|null The doc comment. 540 | * 541 | * @api 542 | */ 543 | public function getDocComment() 544 | { 545 | return $this->docComment; 546 | } 547 | } 548 | -------------------------------------------------------------------------------- /src/Mandango/Mondator/ClassExtension.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Mandango\Mondator; 13 | 14 | use Mandango\Mondator\Definition\Method; 15 | use Mandango\Mondator\Definition\Property; 16 | use Twig\Environment; 17 | use Twig\Loader\ArrayLoader; 18 | 19 | /** 20 | * ClassExtension is the base class for class extensions. 21 | * 22 | * @author Pablo Díez 23 | * 24 | * @api 25 | */ 26 | abstract class ClassExtension 27 | { 28 | private $options; 29 | private $requiredOptions; 30 | 31 | protected $definitions; 32 | 33 | protected $class; 34 | protected $configClasses; 35 | protected $configClass; 36 | 37 | protected $newClassExtensions; 38 | protected $newConfigClasses; 39 | 40 | protected $twig; 41 | protected $twigTempDir; 42 | 43 | /** 44 | * Constructor. 45 | * 46 | * @param array $options An array of options. 47 | * 48 | * @api 49 | */ 50 | public function __construct(array $options = array()) 51 | { 52 | $this->options = array(); 53 | $this->requiredOptions = array(); 54 | 55 | $this->setUp(); 56 | 57 | foreach ($options as $name => $value) { 58 | $this->setOption($name, $value); 59 | } 60 | 61 | // required options 62 | if ($diff = array_diff($this->requiredOptions, array_keys($options))) { 63 | throw new \RuntimeException(sprintf('%s requires the options: "%s".', get_class($this), implode(', ', $diff))); 64 | } 65 | } 66 | 67 | /** 68 | * Set up the extension. 69 | * 70 | * @api 71 | */ 72 | protected function setUp() 73 | { 74 | } 75 | 76 | /** 77 | * Add an option. 78 | * 79 | * @param string $name The option name. 80 | * @param mixed $defaultValue The default value (optional, null by default). 81 | * 82 | * @api 83 | */ 84 | protected function addOption($name, $defaultValue = null) 85 | { 86 | $this->options[$name] = $defaultValue; 87 | } 88 | 89 | /** 90 | * Add options. 91 | * 92 | * @param array $options An array with options (name as key and default value as value). 93 | * 94 | * @api 95 | */ 96 | protected function addOptions(array $options) 97 | { 98 | foreach ($options as $name => $defaultValue) { 99 | $this->addOption($name, $defaultValue); 100 | } 101 | } 102 | 103 | /** 104 | * Add a required option. 105 | * 106 | * @param string $name The option name. 107 | * 108 | * @api 109 | */ 110 | protected function addRequiredOption($name) 111 | { 112 | $this->addOption($name); 113 | 114 | $this->requiredOptions[] = $name; 115 | } 116 | 117 | /** 118 | * Add required options. 119 | * 120 | * @param array $options An array with the name of the required option as value. 121 | * 122 | * @api 123 | */ 124 | protected function addRequiredOptions(array $options) 125 | { 126 | foreach ($options as $name) { 127 | $this->addRequiredOption($name); 128 | } 129 | } 130 | 131 | /** 132 | * Returns if exists an option. 133 | * 134 | * @param string $name The name. 135 | * 136 | * @return bool Returns true if the option exists, false otherwise. 137 | * 138 | * @api 139 | */ 140 | public function hasOption($name) 141 | { 142 | return array_key_exists($name, $this->options); 143 | } 144 | 145 | /** 146 | * Set an option. 147 | * 148 | * @param string $name The name. 149 | * @param mixed $value The value. 150 | * 151 | * @throws \InvalidArgumentException If the option does not exists. 152 | * 153 | * @api 154 | */ 155 | public function setOption($name, $value) 156 | { 157 | if (!$this->hasOption($name)) { 158 | throw new \InvalidArgumentException(sprintf('The option "%s" does not exists.', $name)); 159 | } 160 | 161 | $this->options[$name] = $value; 162 | } 163 | 164 | /** 165 | * Returns the options. 166 | * 167 | * @return array The options. 168 | * 169 | * @api 170 | */ 171 | public function getOptions() 172 | { 173 | return $this->options; 174 | } 175 | 176 | /** 177 | * Return an option. 178 | * 179 | * @param string $name The name. 180 | * 181 | * @return mixed The value of the option. 182 | * 183 | * @throws \InvalidArgumentException If the options does not exists. 184 | * 185 | * @api 186 | */ 187 | public function getOption($name) 188 | { 189 | if (!$this->hasOption($name)) { 190 | throw new \InvalidArgumentException(sprintf('The option "%s" does not exists.', $name)); 191 | } 192 | 193 | return $this->options[$name]; 194 | } 195 | 196 | /** 197 | * New class extensions process. 198 | * 199 | * @param string $class The class. 200 | * @param \ArrayObject $configClasses The config classes. 201 | * @param \ArrayObject $newClassExtensions The new class extensions. 202 | * 203 | * @api 204 | */ 205 | public function newClassExtensionsProcess($class, \ArrayObject $configClasses, \ArrayObject $newClassExtensions) 206 | { 207 | $this->class = $class; 208 | $this->configClasses = $configClasses; 209 | $this->configClass = $configClasses[$class]; 210 | $this->newClassExtensions = $newClassExtensions; 211 | 212 | $this->doNewClassExtensionsProcess(); 213 | 214 | $this->class = null; 215 | $this->configClasses = null; 216 | $this->configClass = null; 217 | $this->newClassExtensions = null; 218 | } 219 | 220 | /** 221 | * Do the new class extensions process. 222 | * 223 | * Here you can add new class extensions. 224 | * 225 | * @api 226 | */ 227 | protected function doNewClassExtensionsProcess() 228 | { 229 | } 230 | 231 | /** 232 | * New config classes process. 233 | * 234 | * @param string $class The class. 235 | * @param \ArrayObject $configClasses The config classes. 236 | * @param \ArrayObject $newConfigClasses The new config classes. 237 | * 238 | * @api 239 | */ 240 | public function newConfigClassesProcess($class, \ArrayObject $configClasses, \ArrayObject $newConfigClasses) 241 | { 242 | $this->class = $class; 243 | $this->configClasses = $configClasses; 244 | $this->configClass = $configClasses[$class]; 245 | $this->newConfigClasses = $newConfigClasses; 246 | 247 | $this->doNewConfigClassesProcess(); 248 | 249 | $this->class = null; 250 | $this->configClasses = null; 251 | $this->configClass = null; 252 | $this->newConfigClasses = null; 253 | } 254 | 255 | /** 256 | * Do the new config classes process. 257 | * 258 | * Here you can add new config classes, and change the config classes 259 | * if it is necessary to build the new config classes. 260 | * 261 | * @api 262 | */ 263 | protected function doNewConfigClassesProcess() 264 | { 265 | } 266 | 267 | /** 268 | * Process the config class. 269 | * 270 | * @param string $class The class. 271 | * @param \ArrayObject $configClasses The config classes. 272 | * 273 | * @api 274 | */ 275 | public function configClassProcess($class, \ArrayObject $configClasses) 276 | { 277 | $this->class = $class; 278 | $this->configClasses = $configClasses; 279 | $this->configClass = $configClasses[$class]; 280 | 281 | $this->doConfigClassProcess(); 282 | 283 | $this->class = null; 284 | $this->configClasses = null; 285 | $this->configClass = null; 286 | } 287 | 288 | /** 289 | * Do the config class process. 290 | * 291 | * Here you can modify the config class. 292 | * 293 | * @api 294 | */ 295 | protected function doConfigClassProcess() 296 | { 297 | } 298 | 299 | 300 | /** 301 | * Process the class. 302 | * 303 | * @param string $class The class. 304 | * @param \ArrayObject $configClasses The config classes. 305 | * @param Mandango\Mondator\Container $container The container. 306 | * 307 | * @api 308 | */ 309 | public function classProcess($class, \ArrayObject $configClasses, Container $container) 310 | { 311 | $this->class = $class; 312 | $this->configClasses = $configClasses; 313 | $this->configClass = $configClasses[$class]; 314 | $this->definitions = $container; 315 | 316 | $this->doClassProcess(); 317 | 318 | $this->class = null; 319 | $this->configClasses = null; 320 | $this->configClass = null; 321 | $this->definitions = null; 322 | } 323 | 324 | /** 325 | * Do the class process. 326 | * 327 | * @api 328 | */ 329 | protected function doClassProcess() 330 | { 331 | } 332 | 333 | /** 334 | * Twig. 335 | */ 336 | protected function processTemplate(Definition $definition, $name, array $variables = array()) 337 | { 338 | $twig = $this->getTwig(); 339 | 340 | $variables['extension'] = $this; 341 | $variables['options'] = $this->options; 342 | $variables['class'] = $this->class; 343 | $variables['config_class'] = $this->configClass; 344 | $variables['config_classes'] = $this->configClasses; 345 | 346 | $template = $twig->createTemplate($name); 347 | $result = $template->render($variables); 348 | 349 | // properties 350 | $expression = '/ 351 | (?P\ \ \ \ \/\*\*\n[\s\S]*\ \ \ \ \ \*\/)?\n? 352 | \ \ \ \ (?Pstatic\ )? 353 | (?Ppublic|protected|private) 354 | \s 355 | \$ 356 | (?P[a-zA-Z0-9_]+) 357 | (?P\={1}[^;]*) 358 | ; 359 | /xU'; 360 | preg_match_all($expression, $result, $matches); 361 | 362 | for ($i = 0; $i <= count($matches[0]) - 1; $i++) { 363 | $value=null; 364 | $result=str_replace($matches[0][$i], '', $result); 365 | if(!empty($matches['value'][$i])){ 366 | eval('$value'.$matches['value'][$i].';'); 367 | } 368 | $property = new Property($matches['visibility'][$i], $matches['name'][$i], $value); 369 | if ($matches['static'][$i]) { 370 | $property->setStatic(true); 371 | } 372 | if ($matches['docComment'][$i]) { 373 | $property->setDocComment($matches['docComment'][$i]); 374 | } 375 | $definition->addProperty($property); 376 | } 377 | 378 | // methods 379 | $expression = '/ 380 | (?P\ \ \ \ \/\*\*\n[\s\S]*\ \ \ \ \ \*\/)?\n 381 | \ \ \ \ (?Pstatic\ )? 382 | (?Ppublic|protected|private) 383 | \s 384 | function 385 | \s 386 | (?P[a-zA-Z0-9_]+) 387 | \((?P[$a-zA-Z0-9_\\\=\(\), ]*)\) 388 | \n 389 | \ \ \ \ \{ 390 | (?P[\s\S]*) 391 | \n\ \ \ \ \} 392 | /xU'; 393 | preg_match_all($expression, $result, $matches); 394 | 395 | for ($i = 0; $i <= count($matches[0]) - 1; $i++) { 396 | $code = trim($matches['code'][$i], "\n"); 397 | $method = new Method($matches['visibility'][$i], $matches['name'][$i], $matches['arguments'][$i], $code); 398 | if ($matches['static'][$i]) { 399 | $method->setStatic(true); 400 | } 401 | if ($matches['docComment'][$i]) { 402 | $method->setDocComment($matches['docComment'][$i]); 403 | } 404 | $definition->addMethod($method); 405 | } 406 | } 407 | 408 | public function getTwig() 409 | { 410 | if (null === $this->twig) { 411 | if (!class_exists('Twig\Environment')) { 412 | throw new \RuntimeException('Twig is required to use templates.'); 413 | } 414 | 415 | $loader = new ArrayLoader(); 416 | $twig = new Environment($loader, array( 417 | 'autoescape' => false, 418 | 'strict_variables' => true, 419 | 'debug' => true, 420 | 'cache' => $this->twigTempDir = sys_get_temp_dir().'/'.uniqid('mondator_'), 421 | )); 422 | 423 | $this->configureTwig($twig); 424 | 425 | $this->twig = $twig; 426 | } 427 | 428 | return $this->twig; 429 | } 430 | 431 | protected function configureTwig(Environment $twig) 432 | { 433 | } 434 | 435 | /* 436 | * Tools. 437 | */ 438 | protected function createClassExtensionFromArray(array $data) 439 | { 440 | if (!isset($data['class'])) { 441 | throw new \InvalidArgumentException(sprintf('The extension does not have class.')); 442 | } 443 | 444 | return new $data['class'](isset($data['options']) ? $data['options'] : array()); 445 | } 446 | 447 | private function removeDir($target) 448 | { 449 | $fp = opendir($target); 450 | while (false !== $file = readdir($fp)) { 451 | if (in_array($file, array('.', '..'))) { 452 | continue; 453 | } 454 | 455 | if (is_dir($target.'/'.$file)) { 456 | self::removeDir($target.'/'.$file); 457 | } else { 458 | unlink($target.'/'.$file); 459 | } 460 | } 461 | closedir($fp); 462 | rmdir($target); 463 | } 464 | 465 | public function __destruct() 466 | { 467 | if ($this->twigTempDir && is_dir($this->twigTempDir)) { 468 | $this->removeDir($this->twigTempDir); 469 | } 470 | } 471 | } 472 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "52dd3cc260564e8a9233f72d1a7e3579", 8 | "packages": [ 9 | { 10 | "name": "symfony/deprecation-contracts", 11 | "version": "v3.5.1", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/symfony/deprecation-contracts.git", 15 | "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", 20 | "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=8.1" 25 | }, 26 | "type": "library", 27 | "extra": { 28 | "branch-alias": { 29 | "dev-main": "3.5-dev" 30 | }, 31 | "thanks": { 32 | "name": "symfony/contracts", 33 | "url": "https://github.com/symfony/contracts" 34 | } 35 | }, 36 | "autoload": { 37 | "files": [ 38 | "function.php" 39 | ] 40 | }, 41 | "notification-url": "https://packagist.org/downloads/", 42 | "license": [ 43 | "MIT" 44 | ], 45 | "authors": [ 46 | { 47 | "name": "Nicolas Grekas", 48 | "email": "p@tchwork.com" 49 | }, 50 | { 51 | "name": "Symfony Community", 52 | "homepage": "https://symfony.com/contributors" 53 | } 54 | ], 55 | "description": "A generic function and convention to trigger deprecation notices", 56 | "homepage": "https://symfony.com", 57 | "support": { 58 | "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" 59 | }, 60 | "funding": [ 61 | { 62 | "url": "https://symfony.com/sponsor", 63 | "type": "custom" 64 | }, 65 | { 66 | "url": "https://github.com/fabpot", 67 | "type": "github" 68 | }, 69 | { 70 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 71 | "type": "tidelift" 72 | } 73 | ], 74 | "time": "2024-09-25T14:20:29+00:00" 75 | }, 76 | { 77 | "name": "symfony/polyfill-ctype", 78 | "version": "v1.31.0", 79 | "source": { 80 | "type": "git", 81 | "url": "https://github.com/symfony/polyfill-ctype.git", 82 | "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" 83 | }, 84 | "dist": { 85 | "type": "zip", 86 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", 87 | "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", 88 | "shasum": "" 89 | }, 90 | "require": { 91 | "php": ">=7.2" 92 | }, 93 | "provide": { 94 | "ext-ctype": "*" 95 | }, 96 | "suggest": { 97 | "ext-ctype": "For best performance" 98 | }, 99 | "type": "library", 100 | "extra": { 101 | "thanks": { 102 | "name": "symfony/polyfill", 103 | "url": "https://github.com/symfony/polyfill" 104 | } 105 | }, 106 | "autoload": { 107 | "files": [ 108 | "bootstrap.php" 109 | ], 110 | "psr-4": { 111 | "Symfony\\Polyfill\\Ctype\\": "" 112 | } 113 | }, 114 | "notification-url": "https://packagist.org/downloads/", 115 | "license": [ 116 | "MIT" 117 | ], 118 | "authors": [ 119 | { 120 | "name": "Gert de Pagter", 121 | "email": "BackEndTea@gmail.com" 122 | }, 123 | { 124 | "name": "Symfony Community", 125 | "homepage": "https://symfony.com/contributors" 126 | } 127 | ], 128 | "description": "Symfony polyfill for ctype functions", 129 | "homepage": "https://symfony.com", 130 | "keywords": [ 131 | "compatibility", 132 | "ctype", 133 | "polyfill", 134 | "portable" 135 | ], 136 | "support": { 137 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" 138 | }, 139 | "funding": [ 140 | { 141 | "url": "https://symfony.com/sponsor", 142 | "type": "custom" 143 | }, 144 | { 145 | "url": "https://github.com/fabpot", 146 | "type": "github" 147 | }, 148 | { 149 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 150 | "type": "tidelift" 151 | } 152 | ], 153 | "time": "2024-09-09T11:45:10+00:00" 154 | }, 155 | { 156 | "name": "symfony/polyfill-mbstring", 157 | "version": "v1.31.0", 158 | "source": { 159 | "type": "git", 160 | "url": "https://github.com/symfony/polyfill-mbstring.git", 161 | "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" 162 | }, 163 | "dist": { 164 | "type": "zip", 165 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", 166 | "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", 167 | "shasum": "" 168 | }, 169 | "require": { 170 | "php": ">=7.2" 171 | }, 172 | "provide": { 173 | "ext-mbstring": "*" 174 | }, 175 | "suggest": { 176 | "ext-mbstring": "For best performance" 177 | }, 178 | "type": "library", 179 | "extra": { 180 | "thanks": { 181 | "name": "symfony/polyfill", 182 | "url": "https://github.com/symfony/polyfill" 183 | } 184 | }, 185 | "autoload": { 186 | "files": [ 187 | "bootstrap.php" 188 | ], 189 | "psr-4": { 190 | "Symfony\\Polyfill\\Mbstring\\": "" 191 | } 192 | }, 193 | "notification-url": "https://packagist.org/downloads/", 194 | "license": [ 195 | "MIT" 196 | ], 197 | "authors": [ 198 | { 199 | "name": "Nicolas Grekas", 200 | "email": "p@tchwork.com" 201 | }, 202 | { 203 | "name": "Symfony Community", 204 | "homepage": "https://symfony.com/contributors" 205 | } 206 | ], 207 | "description": "Symfony polyfill for the Mbstring extension", 208 | "homepage": "https://symfony.com", 209 | "keywords": [ 210 | "compatibility", 211 | "mbstring", 212 | "polyfill", 213 | "portable", 214 | "shim" 215 | ], 216 | "support": { 217 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" 218 | }, 219 | "funding": [ 220 | { 221 | "url": "https://symfony.com/sponsor", 222 | "type": "custom" 223 | }, 224 | { 225 | "url": "https://github.com/fabpot", 226 | "type": "github" 227 | }, 228 | { 229 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 230 | "type": "tidelift" 231 | } 232 | ], 233 | "time": "2024-09-09T11:45:10+00:00" 234 | }, 235 | { 236 | "name": "symfony/polyfill-php81", 237 | "version": "v1.31.0", 238 | "source": { 239 | "type": "git", 240 | "url": "https://github.com/symfony/polyfill-php81.git", 241 | "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" 242 | }, 243 | "dist": { 244 | "type": "zip", 245 | "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", 246 | "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", 247 | "shasum": "" 248 | }, 249 | "require": { 250 | "php": ">=7.2" 251 | }, 252 | "type": "library", 253 | "extra": { 254 | "thanks": { 255 | "name": "symfony/polyfill", 256 | "url": "https://github.com/symfony/polyfill" 257 | } 258 | }, 259 | "autoload": { 260 | "files": [ 261 | "bootstrap.php" 262 | ], 263 | "psr-4": { 264 | "Symfony\\Polyfill\\Php81\\": "" 265 | }, 266 | "classmap": [ 267 | "Resources/stubs" 268 | ] 269 | }, 270 | "notification-url": "https://packagist.org/downloads/", 271 | "license": [ 272 | "MIT" 273 | ], 274 | "authors": [ 275 | { 276 | "name": "Nicolas Grekas", 277 | "email": "p@tchwork.com" 278 | }, 279 | { 280 | "name": "Symfony Community", 281 | "homepage": "https://symfony.com/contributors" 282 | } 283 | ], 284 | "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", 285 | "homepage": "https://symfony.com", 286 | "keywords": [ 287 | "compatibility", 288 | "polyfill", 289 | "portable", 290 | "shim" 291 | ], 292 | "support": { 293 | "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" 294 | }, 295 | "funding": [ 296 | { 297 | "url": "https://symfony.com/sponsor", 298 | "type": "custom" 299 | }, 300 | { 301 | "url": "https://github.com/fabpot", 302 | "type": "github" 303 | }, 304 | { 305 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 306 | "type": "tidelift" 307 | } 308 | ], 309 | "time": "2024-09-09T11:45:10+00:00" 310 | }, 311 | { 312 | "name": "twig/twig", 313 | "version": "v3.15.0", 314 | "source": { 315 | "type": "git", 316 | "url": "https://github.com/twigphp/Twig.git", 317 | "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02" 318 | }, 319 | "dist": { 320 | "type": "zip", 321 | "url": "https://api.github.com/repos/twigphp/Twig/zipball/2d5b3964cc21d0188633d7ddce732dc8e874db02", 322 | "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02", 323 | "shasum": "" 324 | }, 325 | "require": { 326 | "php": ">=8.0.2", 327 | "symfony/deprecation-contracts": "^2.5|^3", 328 | "symfony/polyfill-ctype": "^1.8", 329 | "symfony/polyfill-mbstring": "^1.3", 330 | "symfony/polyfill-php81": "^1.29" 331 | }, 332 | "require-dev": { 333 | "psr/container": "^1.0|^2.0", 334 | "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" 335 | }, 336 | "type": "library", 337 | "autoload": { 338 | "files": [ 339 | "src/Resources/core.php", 340 | "src/Resources/debug.php", 341 | "src/Resources/escaper.php", 342 | "src/Resources/string_loader.php" 343 | ], 344 | "psr-4": { 345 | "Twig\\": "src/" 346 | } 347 | }, 348 | "notification-url": "https://packagist.org/downloads/", 349 | "license": [ 350 | "BSD-3-Clause" 351 | ], 352 | "authors": [ 353 | { 354 | "name": "Fabien Potencier", 355 | "email": "fabien@symfony.com", 356 | "homepage": "http://fabien.potencier.org", 357 | "role": "Lead Developer" 358 | }, 359 | { 360 | "name": "Twig Team", 361 | "role": "Contributors" 362 | }, 363 | { 364 | "name": "Armin Ronacher", 365 | "email": "armin.ronacher@active-4.com", 366 | "role": "Project Founder" 367 | } 368 | ], 369 | "description": "Twig, the flexible, fast, and secure template language for PHP", 370 | "homepage": "https://twig.symfony.com", 371 | "keywords": [ 372 | "templating" 373 | ], 374 | "support": { 375 | "issues": "https://github.com/twigphp/Twig/issues", 376 | "source": "https://github.com/twigphp/Twig/tree/v3.15.0" 377 | }, 378 | "funding": [ 379 | { 380 | "url": "https://github.com/fabpot", 381 | "type": "github" 382 | }, 383 | { 384 | "url": "https://tidelift.com/funding/github/packagist/twig/twig", 385 | "type": "tidelift" 386 | } 387 | ], 388 | "time": "2024-11-17T15:59:19+00:00" 389 | } 390 | ], 391 | "packages-dev": [ 392 | { 393 | "name": "myclabs/deep-copy", 394 | "version": "1.12.1", 395 | "source": { 396 | "type": "git", 397 | "url": "https://github.com/myclabs/DeepCopy.git", 398 | "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" 399 | }, 400 | "dist": { 401 | "type": "zip", 402 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", 403 | "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", 404 | "shasum": "" 405 | }, 406 | "require": { 407 | "php": "^7.1 || ^8.0" 408 | }, 409 | "conflict": { 410 | "doctrine/collections": "<1.6.8", 411 | "doctrine/common": "<2.13.3 || >=3 <3.2.2" 412 | }, 413 | "require-dev": { 414 | "doctrine/collections": "^1.6.8", 415 | "doctrine/common": "^2.13.3 || ^3.2.2", 416 | "phpspec/prophecy": "^1.10", 417 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" 418 | }, 419 | "type": "library", 420 | "autoload": { 421 | "files": [ 422 | "src/DeepCopy/deep_copy.php" 423 | ], 424 | "psr-4": { 425 | "DeepCopy\\": "src/DeepCopy/" 426 | } 427 | }, 428 | "notification-url": "https://packagist.org/downloads/", 429 | "license": [ 430 | "MIT" 431 | ], 432 | "description": "Create deep copies (clones) of your objects", 433 | "keywords": [ 434 | "clone", 435 | "copy", 436 | "duplicate", 437 | "object", 438 | "object graph" 439 | ], 440 | "support": { 441 | "issues": "https://github.com/myclabs/DeepCopy/issues", 442 | "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" 443 | }, 444 | "funding": [ 445 | { 446 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", 447 | "type": "tidelift" 448 | } 449 | ], 450 | "time": "2024-11-08T17:47:46+00:00" 451 | }, 452 | { 453 | "name": "nikic/php-parser", 454 | "version": "v5.3.1", 455 | "source": { 456 | "type": "git", 457 | "url": "https://github.com/nikic/PHP-Parser.git", 458 | "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" 459 | }, 460 | "dist": { 461 | "type": "zip", 462 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", 463 | "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", 464 | "shasum": "" 465 | }, 466 | "require": { 467 | "ext-ctype": "*", 468 | "ext-json": "*", 469 | "ext-tokenizer": "*", 470 | "php": ">=7.4" 471 | }, 472 | "require-dev": { 473 | "ircmaxell/php-yacc": "^0.0.7", 474 | "phpunit/phpunit": "^9.0" 475 | }, 476 | "bin": [ 477 | "bin/php-parse" 478 | ], 479 | "type": "library", 480 | "extra": { 481 | "branch-alias": { 482 | "dev-master": "5.0-dev" 483 | } 484 | }, 485 | "autoload": { 486 | "psr-4": { 487 | "PhpParser\\": "lib/PhpParser" 488 | } 489 | }, 490 | "notification-url": "https://packagist.org/downloads/", 491 | "license": [ 492 | "BSD-3-Clause" 493 | ], 494 | "authors": [ 495 | { 496 | "name": "Nikita Popov" 497 | } 498 | ], 499 | "description": "A PHP parser written in PHP", 500 | "keywords": [ 501 | "parser", 502 | "php" 503 | ], 504 | "support": { 505 | "issues": "https://github.com/nikic/PHP-Parser/issues", 506 | "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" 507 | }, 508 | "time": "2024-10-08T18:51:32+00:00" 509 | }, 510 | { 511 | "name": "phar-io/manifest", 512 | "version": "2.0.4", 513 | "source": { 514 | "type": "git", 515 | "url": "https://github.com/phar-io/manifest.git", 516 | "reference": "54750ef60c58e43759730615a392c31c80e23176" 517 | }, 518 | "dist": { 519 | "type": "zip", 520 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", 521 | "reference": "54750ef60c58e43759730615a392c31c80e23176", 522 | "shasum": "" 523 | }, 524 | "require": { 525 | "ext-dom": "*", 526 | "ext-libxml": "*", 527 | "ext-phar": "*", 528 | "ext-xmlwriter": "*", 529 | "phar-io/version": "^3.0.1", 530 | "php": "^7.2 || ^8.0" 531 | }, 532 | "type": "library", 533 | "extra": { 534 | "branch-alias": { 535 | "dev-master": "2.0.x-dev" 536 | } 537 | }, 538 | "autoload": { 539 | "classmap": [ 540 | "src/" 541 | ] 542 | }, 543 | "notification-url": "https://packagist.org/downloads/", 544 | "license": [ 545 | "BSD-3-Clause" 546 | ], 547 | "authors": [ 548 | { 549 | "name": "Arne Blankerts", 550 | "email": "arne@blankerts.de", 551 | "role": "Developer" 552 | }, 553 | { 554 | "name": "Sebastian Heuer", 555 | "email": "sebastian@phpeople.de", 556 | "role": "Developer" 557 | }, 558 | { 559 | "name": "Sebastian Bergmann", 560 | "email": "sebastian@phpunit.de", 561 | "role": "Developer" 562 | } 563 | ], 564 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 565 | "support": { 566 | "issues": "https://github.com/phar-io/manifest/issues", 567 | "source": "https://github.com/phar-io/manifest/tree/2.0.4" 568 | }, 569 | "funding": [ 570 | { 571 | "url": "https://github.com/theseer", 572 | "type": "github" 573 | } 574 | ], 575 | "time": "2024-03-03T12:33:53+00:00" 576 | }, 577 | { 578 | "name": "phar-io/version", 579 | "version": "3.2.1", 580 | "source": { 581 | "type": "git", 582 | "url": "https://github.com/phar-io/version.git", 583 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" 584 | }, 585 | "dist": { 586 | "type": "zip", 587 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 588 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", 589 | "shasum": "" 590 | }, 591 | "require": { 592 | "php": "^7.2 || ^8.0" 593 | }, 594 | "type": "library", 595 | "autoload": { 596 | "classmap": [ 597 | "src/" 598 | ] 599 | }, 600 | "notification-url": "https://packagist.org/downloads/", 601 | "license": [ 602 | "BSD-3-Clause" 603 | ], 604 | "authors": [ 605 | { 606 | "name": "Arne Blankerts", 607 | "email": "arne@blankerts.de", 608 | "role": "Developer" 609 | }, 610 | { 611 | "name": "Sebastian Heuer", 612 | "email": "sebastian@phpeople.de", 613 | "role": "Developer" 614 | }, 615 | { 616 | "name": "Sebastian Bergmann", 617 | "email": "sebastian@phpunit.de", 618 | "role": "Developer" 619 | } 620 | ], 621 | "description": "Library for handling version information and constraints", 622 | "support": { 623 | "issues": "https://github.com/phar-io/version/issues", 624 | "source": "https://github.com/phar-io/version/tree/3.2.1" 625 | }, 626 | "time": "2022-02-21T01:04:05+00:00" 627 | }, 628 | { 629 | "name": "phpunit/php-code-coverage", 630 | "version": "10.1.16", 631 | "source": { 632 | "type": "git", 633 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 634 | "reference": "7e308268858ed6baedc8704a304727d20bc07c77" 635 | }, 636 | "dist": { 637 | "type": "zip", 638 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", 639 | "reference": "7e308268858ed6baedc8704a304727d20bc07c77", 640 | "shasum": "" 641 | }, 642 | "require": { 643 | "ext-dom": "*", 644 | "ext-libxml": "*", 645 | "ext-xmlwriter": "*", 646 | "nikic/php-parser": "^4.19.1 || ^5.1.0", 647 | "php": ">=8.1", 648 | "phpunit/php-file-iterator": "^4.1.0", 649 | "phpunit/php-text-template": "^3.0.1", 650 | "sebastian/code-unit-reverse-lookup": "^3.0.0", 651 | "sebastian/complexity": "^3.2.0", 652 | "sebastian/environment": "^6.1.0", 653 | "sebastian/lines-of-code": "^2.0.2", 654 | "sebastian/version": "^4.0.1", 655 | "theseer/tokenizer": "^1.2.3" 656 | }, 657 | "require-dev": { 658 | "phpunit/phpunit": "^10.1" 659 | }, 660 | "suggest": { 661 | "ext-pcov": "PHP extension that provides line coverage", 662 | "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" 663 | }, 664 | "type": "library", 665 | "extra": { 666 | "branch-alias": { 667 | "dev-main": "10.1.x-dev" 668 | } 669 | }, 670 | "autoload": { 671 | "classmap": [ 672 | "src/" 673 | ] 674 | }, 675 | "notification-url": "https://packagist.org/downloads/", 676 | "license": [ 677 | "BSD-3-Clause" 678 | ], 679 | "authors": [ 680 | { 681 | "name": "Sebastian Bergmann", 682 | "email": "sebastian@phpunit.de", 683 | "role": "lead" 684 | } 685 | ], 686 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 687 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 688 | "keywords": [ 689 | "coverage", 690 | "testing", 691 | "xunit" 692 | ], 693 | "support": { 694 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 695 | "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", 696 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" 697 | }, 698 | "funding": [ 699 | { 700 | "url": "https://github.com/sebastianbergmann", 701 | "type": "github" 702 | } 703 | ], 704 | "time": "2024-08-22T04:31:57+00:00" 705 | }, 706 | { 707 | "name": "phpunit/php-file-iterator", 708 | "version": "4.1.0", 709 | "source": { 710 | "type": "git", 711 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 712 | "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" 713 | }, 714 | "dist": { 715 | "type": "zip", 716 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", 717 | "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", 718 | "shasum": "" 719 | }, 720 | "require": { 721 | "php": ">=8.1" 722 | }, 723 | "require-dev": { 724 | "phpunit/phpunit": "^10.0" 725 | }, 726 | "type": "library", 727 | "extra": { 728 | "branch-alias": { 729 | "dev-main": "4.0-dev" 730 | } 731 | }, 732 | "autoload": { 733 | "classmap": [ 734 | "src/" 735 | ] 736 | }, 737 | "notification-url": "https://packagist.org/downloads/", 738 | "license": [ 739 | "BSD-3-Clause" 740 | ], 741 | "authors": [ 742 | { 743 | "name": "Sebastian Bergmann", 744 | "email": "sebastian@phpunit.de", 745 | "role": "lead" 746 | } 747 | ], 748 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 749 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 750 | "keywords": [ 751 | "filesystem", 752 | "iterator" 753 | ], 754 | "support": { 755 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 756 | "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", 757 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" 758 | }, 759 | "funding": [ 760 | { 761 | "url": "https://github.com/sebastianbergmann", 762 | "type": "github" 763 | } 764 | ], 765 | "time": "2023-08-31T06:24:48+00:00" 766 | }, 767 | { 768 | "name": "phpunit/php-invoker", 769 | "version": "4.0.0", 770 | "source": { 771 | "type": "git", 772 | "url": "https://github.com/sebastianbergmann/php-invoker.git", 773 | "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" 774 | }, 775 | "dist": { 776 | "type": "zip", 777 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", 778 | "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", 779 | "shasum": "" 780 | }, 781 | "require": { 782 | "php": ">=8.1" 783 | }, 784 | "require-dev": { 785 | "ext-pcntl": "*", 786 | "phpunit/phpunit": "^10.0" 787 | }, 788 | "suggest": { 789 | "ext-pcntl": "*" 790 | }, 791 | "type": "library", 792 | "extra": { 793 | "branch-alias": { 794 | "dev-main": "4.0-dev" 795 | } 796 | }, 797 | "autoload": { 798 | "classmap": [ 799 | "src/" 800 | ] 801 | }, 802 | "notification-url": "https://packagist.org/downloads/", 803 | "license": [ 804 | "BSD-3-Clause" 805 | ], 806 | "authors": [ 807 | { 808 | "name": "Sebastian Bergmann", 809 | "email": "sebastian@phpunit.de", 810 | "role": "lead" 811 | } 812 | ], 813 | "description": "Invoke callables with a timeout", 814 | "homepage": "https://github.com/sebastianbergmann/php-invoker/", 815 | "keywords": [ 816 | "process" 817 | ], 818 | "support": { 819 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues", 820 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" 821 | }, 822 | "funding": [ 823 | { 824 | "url": "https://github.com/sebastianbergmann", 825 | "type": "github" 826 | } 827 | ], 828 | "time": "2023-02-03T06:56:09+00:00" 829 | }, 830 | { 831 | "name": "phpunit/php-text-template", 832 | "version": "3.0.1", 833 | "source": { 834 | "type": "git", 835 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 836 | "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" 837 | }, 838 | "dist": { 839 | "type": "zip", 840 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", 841 | "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", 842 | "shasum": "" 843 | }, 844 | "require": { 845 | "php": ">=8.1" 846 | }, 847 | "require-dev": { 848 | "phpunit/phpunit": "^10.0" 849 | }, 850 | "type": "library", 851 | "extra": { 852 | "branch-alias": { 853 | "dev-main": "3.0-dev" 854 | } 855 | }, 856 | "autoload": { 857 | "classmap": [ 858 | "src/" 859 | ] 860 | }, 861 | "notification-url": "https://packagist.org/downloads/", 862 | "license": [ 863 | "BSD-3-Clause" 864 | ], 865 | "authors": [ 866 | { 867 | "name": "Sebastian Bergmann", 868 | "email": "sebastian@phpunit.de", 869 | "role": "lead" 870 | } 871 | ], 872 | "description": "Simple template engine.", 873 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 874 | "keywords": [ 875 | "template" 876 | ], 877 | "support": { 878 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 879 | "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", 880 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" 881 | }, 882 | "funding": [ 883 | { 884 | "url": "https://github.com/sebastianbergmann", 885 | "type": "github" 886 | } 887 | ], 888 | "time": "2023-08-31T14:07:24+00:00" 889 | }, 890 | { 891 | "name": "phpunit/php-timer", 892 | "version": "6.0.0", 893 | "source": { 894 | "type": "git", 895 | "url": "https://github.com/sebastianbergmann/php-timer.git", 896 | "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" 897 | }, 898 | "dist": { 899 | "type": "zip", 900 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", 901 | "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", 902 | "shasum": "" 903 | }, 904 | "require": { 905 | "php": ">=8.1" 906 | }, 907 | "require-dev": { 908 | "phpunit/phpunit": "^10.0" 909 | }, 910 | "type": "library", 911 | "extra": { 912 | "branch-alias": { 913 | "dev-main": "6.0-dev" 914 | } 915 | }, 916 | "autoload": { 917 | "classmap": [ 918 | "src/" 919 | ] 920 | }, 921 | "notification-url": "https://packagist.org/downloads/", 922 | "license": [ 923 | "BSD-3-Clause" 924 | ], 925 | "authors": [ 926 | { 927 | "name": "Sebastian Bergmann", 928 | "email": "sebastian@phpunit.de", 929 | "role": "lead" 930 | } 931 | ], 932 | "description": "Utility class for timing", 933 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 934 | "keywords": [ 935 | "timer" 936 | ], 937 | "support": { 938 | "issues": "https://github.com/sebastianbergmann/php-timer/issues", 939 | "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" 940 | }, 941 | "funding": [ 942 | { 943 | "url": "https://github.com/sebastianbergmann", 944 | "type": "github" 945 | } 946 | ], 947 | "time": "2023-02-03T06:57:52+00:00" 948 | }, 949 | { 950 | "name": "phpunit/phpunit", 951 | "version": "10.5.38", 952 | "source": { 953 | "type": "git", 954 | "url": "https://github.com/sebastianbergmann/phpunit.git", 955 | "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" 956 | }, 957 | "dist": { 958 | "type": "zip", 959 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", 960 | "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", 961 | "shasum": "" 962 | }, 963 | "require": { 964 | "ext-dom": "*", 965 | "ext-json": "*", 966 | "ext-libxml": "*", 967 | "ext-mbstring": "*", 968 | "ext-xml": "*", 969 | "ext-xmlwriter": "*", 970 | "myclabs/deep-copy": "^1.12.0", 971 | "phar-io/manifest": "^2.0.4", 972 | "phar-io/version": "^3.2.1", 973 | "php": ">=8.1", 974 | "phpunit/php-code-coverage": "^10.1.16", 975 | "phpunit/php-file-iterator": "^4.1.0", 976 | "phpunit/php-invoker": "^4.0.0", 977 | "phpunit/php-text-template": "^3.0.1", 978 | "phpunit/php-timer": "^6.0.0", 979 | "sebastian/cli-parser": "^2.0.1", 980 | "sebastian/code-unit": "^2.0.0", 981 | "sebastian/comparator": "^5.0.3", 982 | "sebastian/diff": "^5.1.1", 983 | "sebastian/environment": "^6.1.0", 984 | "sebastian/exporter": "^5.1.2", 985 | "sebastian/global-state": "^6.0.2", 986 | "sebastian/object-enumerator": "^5.0.0", 987 | "sebastian/recursion-context": "^5.0.0", 988 | "sebastian/type": "^4.0.0", 989 | "sebastian/version": "^4.0.1" 990 | }, 991 | "suggest": { 992 | "ext-soap": "To be able to generate mocks based on WSDL files" 993 | }, 994 | "bin": [ 995 | "phpunit" 996 | ], 997 | "type": "library", 998 | "extra": { 999 | "branch-alias": { 1000 | "dev-main": "10.5-dev" 1001 | } 1002 | }, 1003 | "autoload": { 1004 | "files": [ 1005 | "src/Framework/Assert/Functions.php" 1006 | ], 1007 | "classmap": [ 1008 | "src/" 1009 | ] 1010 | }, 1011 | "notification-url": "https://packagist.org/downloads/", 1012 | "license": [ 1013 | "BSD-3-Clause" 1014 | ], 1015 | "authors": [ 1016 | { 1017 | "name": "Sebastian Bergmann", 1018 | "email": "sebastian@phpunit.de", 1019 | "role": "lead" 1020 | } 1021 | ], 1022 | "description": "The PHP Unit Testing framework.", 1023 | "homepage": "https://phpunit.de/", 1024 | "keywords": [ 1025 | "phpunit", 1026 | "testing", 1027 | "xunit" 1028 | ], 1029 | "support": { 1030 | "issues": "https://github.com/sebastianbergmann/phpunit/issues", 1031 | "security": "https://github.com/sebastianbergmann/phpunit/security/policy", 1032 | "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38" 1033 | }, 1034 | "funding": [ 1035 | { 1036 | "url": "https://phpunit.de/sponsors.html", 1037 | "type": "custom" 1038 | }, 1039 | { 1040 | "url": "https://github.com/sebastianbergmann", 1041 | "type": "github" 1042 | }, 1043 | { 1044 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", 1045 | "type": "tidelift" 1046 | } 1047 | ], 1048 | "time": "2024-10-28T13:06:21+00:00" 1049 | }, 1050 | { 1051 | "name": "sebastian/cli-parser", 1052 | "version": "2.0.1", 1053 | "source": { 1054 | "type": "git", 1055 | "url": "https://github.com/sebastianbergmann/cli-parser.git", 1056 | "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" 1057 | }, 1058 | "dist": { 1059 | "type": "zip", 1060 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", 1061 | "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", 1062 | "shasum": "" 1063 | }, 1064 | "require": { 1065 | "php": ">=8.1" 1066 | }, 1067 | "require-dev": { 1068 | "phpunit/phpunit": "^10.0" 1069 | }, 1070 | "type": "library", 1071 | "extra": { 1072 | "branch-alias": { 1073 | "dev-main": "2.0-dev" 1074 | } 1075 | }, 1076 | "autoload": { 1077 | "classmap": [ 1078 | "src/" 1079 | ] 1080 | }, 1081 | "notification-url": "https://packagist.org/downloads/", 1082 | "license": [ 1083 | "BSD-3-Clause" 1084 | ], 1085 | "authors": [ 1086 | { 1087 | "name": "Sebastian Bergmann", 1088 | "email": "sebastian@phpunit.de", 1089 | "role": "lead" 1090 | } 1091 | ], 1092 | "description": "Library for parsing CLI options", 1093 | "homepage": "https://github.com/sebastianbergmann/cli-parser", 1094 | "support": { 1095 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues", 1096 | "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", 1097 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" 1098 | }, 1099 | "funding": [ 1100 | { 1101 | "url": "https://github.com/sebastianbergmann", 1102 | "type": "github" 1103 | } 1104 | ], 1105 | "time": "2024-03-02T07:12:49+00:00" 1106 | }, 1107 | { 1108 | "name": "sebastian/code-unit", 1109 | "version": "2.0.0", 1110 | "source": { 1111 | "type": "git", 1112 | "url": "https://github.com/sebastianbergmann/code-unit.git", 1113 | "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" 1114 | }, 1115 | "dist": { 1116 | "type": "zip", 1117 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", 1118 | "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", 1119 | "shasum": "" 1120 | }, 1121 | "require": { 1122 | "php": ">=8.1" 1123 | }, 1124 | "require-dev": { 1125 | "phpunit/phpunit": "^10.0" 1126 | }, 1127 | "type": "library", 1128 | "extra": { 1129 | "branch-alias": { 1130 | "dev-main": "2.0-dev" 1131 | } 1132 | }, 1133 | "autoload": { 1134 | "classmap": [ 1135 | "src/" 1136 | ] 1137 | }, 1138 | "notification-url": "https://packagist.org/downloads/", 1139 | "license": [ 1140 | "BSD-3-Clause" 1141 | ], 1142 | "authors": [ 1143 | { 1144 | "name": "Sebastian Bergmann", 1145 | "email": "sebastian@phpunit.de", 1146 | "role": "lead" 1147 | } 1148 | ], 1149 | "description": "Collection of value objects that represent the PHP code units", 1150 | "homepage": "https://github.com/sebastianbergmann/code-unit", 1151 | "support": { 1152 | "issues": "https://github.com/sebastianbergmann/code-unit/issues", 1153 | "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" 1154 | }, 1155 | "funding": [ 1156 | { 1157 | "url": "https://github.com/sebastianbergmann", 1158 | "type": "github" 1159 | } 1160 | ], 1161 | "time": "2023-02-03T06:58:43+00:00" 1162 | }, 1163 | { 1164 | "name": "sebastian/code-unit-reverse-lookup", 1165 | "version": "3.0.0", 1166 | "source": { 1167 | "type": "git", 1168 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1169 | "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" 1170 | }, 1171 | "dist": { 1172 | "type": "zip", 1173 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", 1174 | "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", 1175 | "shasum": "" 1176 | }, 1177 | "require": { 1178 | "php": ">=8.1" 1179 | }, 1180 | "require-dev": { 1181 | "phpunit/phpunit": "^10.0" 1182 | }, 1183 | "type": "library", 1184 | "extra": { 1185 | "branch-alias": { 1186 | "dev-main": "3.0-dev" 1187 | } 1188 | }, 1189 | "autoload": { 1190 | "classmap": [ 1191 | "src/" 1192 | ] 1193 | }, 1194 | "notification-url": "https://packagist.org/downloads/", 1195 | "license": [ 1196 | "BSD-3-Clause" 1197 | ], 1198 | "authors": [ 1199 | { 1200 | "name": "Sebastian Bergmann", 1201 | "email": "sebastian@phpunit.de" 1202 | } 1203 | ], 1204 | "description": "Looks up which function or method a line of code belongs to", 1205 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1206 | "support": { 1207 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", 1208 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" 1209 | }, 1210 | "funding": [ 1211 | { 1212 | "url": "https://github.com/sebastianbergmann", 1213 | "type": "github" 1214 | } 1215 | ], 1216 | "time": "2023-02-03T06:59:15+00:00" 1217 | }, 1218 | { 1219 | "name": "sebastian/comparator", 1220 | "version": "5.0.3", 1221 | "source": { 1222 | "type": "git", 1223 | "url": "https://github.com/sebastianbergmann/comparator.git", 1224 | "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" 1225 | }, 1226 | "dist": { 1227 | "type": "zip", 1228 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", 1229 | "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", 1230 | "shasum": "" 1231 | }, 1232 | "require": { 1233 | "ext-dom": "*", 1234 | "ext-mbstring": "*", 1235 | "php": ">=8.1", 1236 | "sebastian/diff": "^5.0", 1237 | "sebastian/exporter": "^5.0" 1238 | }, 1239 | "require-dev": { 1240 | "phpunit/phpunit": "^10.5" 1241 | }, 1242 | "type": "library", 1243 | "extra": { 1244 | "branch-alias": { 1245 | "dev-main": "5.0-dev" 1246 | } 1247 | }, 1248 | "autoload": { 1249 | "classmap": [ 1250 | "src/" 1251 | ] 1252 | }, 1253 | "notification-url": "https://packagist.org/downloads/", 1254 | "license": [ 1255 | "BSD-3-Clause" 1256 | ], 1257 | "authors": [ 1258 | { 1259 | "name": "Sebastian Bergmann", 1260 | "email": "sebastian@phpunit.de" 1261 | }, 1262 | { 1263 | "name": "Jeff Welch", 1264 | "email": "whatthejeff@gmail.com" 1265 | }, 1266 | { 1267 | "name": "Volker Dusch", 1268 | "email": "github@wallbash.com" 1269 | }, 1270 | { 1271 | "name": "Bernhard Schussek", 1272 | "email": "bschussek@2bepublished.at" 1273 | } 1274 | ], 1275 | "description": "Provides the functionality to compare PHP values for equality", 1276 | "homepage": "https://github.com/sebastianbergmann/comparator", 1277 | "keywords": [ 1278 | "comparator", 1279 | "compare", 1280 | "equality" 1281 | ], 1282 | "support": { 1283 | "issues": "https://github.com/sebastianbergmann/comparator/issues", 1284 | "security": "https://github.com/sebastianbergmann/comparator/security/policy", 1285 | "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" 1286 | }, 1287 | "funding": [ 1288 | { 1289 | "url": "https://github.com/sebastianbergmann", 1290 | "type": "github" 1291 | } 1292 | ], 1293 | "time": "2024-10-18T14:56:07+00:00" 1294 | }, 1295 | { 1296 | "name": "sebastian/complexity", 1297 | "version": "3.2.0", 1298 | "source": { 1299 | "type": "git", 1300 | "url": "https://github.com/sebastianbergmann/complexity.git", 1301 | "reference": "68ff824baeae169ec9f2137158ee529584553799" 1302 | }, 1303 | "dist": { 1304 | "type": "zip", 1305 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", 1306 | "reference": "68ff824baeae169ec9f2137158ee529584553799", 1307 | "shasum": "" 1308 | }, 1309 | "require": { 1310 | "nikic/php-parser": "^4.18 || ^5.0", 1311 | "php": ">=8.1" 1312 | }, 1313 | "require-dev": { 1314 | "phpunit/phpunit": "^10.0" 1315 | }, 1316 | "type": "library", 1317 | "extra": { 1318 | "branch-alias": { 1319 | "dev-main": "3.2-dev" 1320 | } 1321 | }, 1322 | "autoload": { 1323 | "classmap": [ 1324 | "src/" 1325 | ] 1326 | }, 1327 | "notification-url": "https://packagist.org/downloads/", 1328 | "license": [ 1329 | "BSD-3-Clause" 1330 | ], 1331 | "authors": [ 1332 | { 1333 | "name": "Sebastian Bergmann", 1334 | "email": "sebastian@phpunit.de", 1335 | "role": "lead" 1336 | } 1337 | ], 1338 | "description": "Library for calculating the complexity of PHP code units", 1339 | "homepage": "https://github.com/sebastianbergmann/complexity", 1340 | "support": { 1341 | "issues": "https://github.com/sebastianbergmann/complexity/issues", 1342 | "security": "https://github.com/sebastianbergmann/complexity/security/policy", 1343 | "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" 1344 | }, 1345 | "funding": [ 1346 | { 1347 | "url": "https://github.com/sebastianbergmann", 1348 | "type": "github" 1349 | } 1350 | ], 1351 | "time": "2023-12-21T08:37:17+00:00" 1352 | }, 1353 | { 1354 | "name": "sebastian/diff", 1355 | "version": "5.1.1", 1356 | "source": { 1357 | "type": "git", 1358 | "url": "https://github.com/sebastianbergmann/diff.git", 1359 | "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" 1360 | }, 1361 | "dist": { 1362 | "type": "zip", 1363 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", 1364 | "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", 1365 | "shasum": "" 1366 | }, 1367 | "require": { 1368 | "php": ">=8.1" 1369 | }, 1370 | "require-dev": { 1371 | "phpunit/phpunit": "^10.0", 1372 | "symfony/process": "^6.4" 1373 | }, 1374 | "type": "library", 1375 | "extra": { 1376 | "branch-alias": { 1377 | "dev-main": "5.1-dev" 1378 | } 1379 | }, 1380 | "autoload": { 1381 | "classmap": [ 1382 | "src/" 1383 | ] 1384 | }, 1385 | "notification-url": "https://packagist.org/downloads/", 1386 | "license": [ 1387 | "BSD-3-Clause" 1388 | ], 1389 | "authors": [ 1390 | { 1391 | "name": "Sebastian Bergmann", 1392 | "email": "sebastian@phpunit.de" 1393 | }, 1394 | { 1395 | "name": "Kore Nordmann", 1396 | "email": "mail@kore-nordmann.de" 1397 | } 1398 | ], 1399 | "description": "Diff implementation", 1400 | "homepage": "https://github.com/sebastianbergmann/diff", 1401 | "keywords": [ 1402 | "diff", 1403 | "udiff", 1404 | "unidiff", 1405 | "unified diff" 1406 | ], 1407 | "support": { 1408 | "issues": "https://github.com/sebastianbergmann/diff/issues", 1409 | "security": "https://github.com/sebastianbergmann/diff/security/policy", 1410 | "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" 1411 | }, 1412 | "funding": [ 1413 | { 1414 | "url": "https://github.com/sebastianbergmann", 1415 | "type": "github" 1416 | } 1417 | ], 1418 | "time": "2024-03-02T07:15:17+00:00" 1419 | }, 1420 | { 1421 | "name": "sebastian/environment", 1422 | "version": "6.1.0", 1423 | "source": { 1424 | "type": "git", 1425 | "url": "https://github.com/sebastianbergmann/environment.git", 1426 | "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" 1427 | }, 1428 | "dist": { 1429 | "type": "zip", 1430 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", 1431 | "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", 1432 | "shasum": "" 1433 | }, 1434 | "require": { 1435 | "php": ">=8.1" 1436 | }, 1437 | "require-dev": { 1438 | "phpunit/phpunit": "^10.0" 1439 | }, 1440 | "suggest": { 1441 | "ext-posix": "*" 1442 | }, 1443 | "type": "library", 1444 | "extra": { 1445 | "branch-alias": { 1446 | "dev-main": "6.1-dev" 1447 | } 1448 | }, 1449 | "autoload": { 1450 | "classmap": [ 1451 | "src/" 1452 | ] 1453 | }, 1454 | "notification-url": "https://packagist.org/downloads/", 1455 | "license": [ 1456 | "BSD-3-Clause" 1457 | ], 1458 | "authors": [ 1459 | { 1460 | "name": "Sebastian Bergmann", 1461 | "email": "sebastian@phpunit.de" 1462 | } 1463 | ], 1464 | "description": "Provides functionality to handle HHVM/PHP environments", 1465 | "homepage": "https://github.com/sebastianbergmann/environment", 1466 | "keywords": [ 1467 | "Xdebug", 1468 | "environment", 1469 | "hhvm" 1470 | ], 1471 | "support": { 1472 | "issues": "https://github.com/sebastianbergmann/environment/issues", 1473 | "security": "https://github.com/sebastianbergmann/environment/security/policy", 1474 | "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" 1475 | }, 1476 | "funding": [ 1477 | { 1478 | "url": "https://github.com/sebastianbergmann", 1479 | "type": "github" 1480 | } 1481 | ], 1482 | "time": "2024-03-23T08:47:14+00:00" 1483 | }, 1484 | { 1485 | "name": "sebastian/exporter", 1486 | "version": "5.1.2", 1487 | "source": { 1488 | "type": "git", 1489 | "url": "https://github.com/sebastianbergmann/exporter.git", 1490 | "reference": "955288482d97c19a372d3f31006ab3f37da47adf" 1491 | }, 1492 | "dist": { 1493 | "type": "zip", 1494 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", 1495 | "reference": "955288482d97c19a372d3f31006ab3f37da47adf", 1496 | "shasum": "" 1497 | }, 1498 | "require": { 1499 | "ext-mbstring": "*", 1500 | "php": ">=8.1", 1501 | "sebastian/recursion-context": "^5.0" 1502 | }, 1503 | "require-dev": { 1504 | "phpunit/phpunit": "^10.0" 1505 | }, 1506 | "type": "library", 1507 | "extra": { 1508 | "branch-alias": { 1509 | "dev-main": "5.1-dev" 1510 | } 1511 | }, 1512 | "autoload": { 1513 | "classmap": [ 1514 | "src/" 1515 | ] 1516 | }, 1517 | "notification-url": "https://packagist.org/downloads/", 1518 | "license": [ 1519 | "BSD-3-Clause" 1520 | ], 1521 | "authors": [ 1522 | { 1523 | "name": "Sebastian Bergmann", 1524 | "email": "sebastian@phpunit.de" 1525 | }, 1526 | { 1527 | "name": "Jeff Welch", 1528 | "email": "whatthejeff@gmail.com" 1529 | }, 1530 | { 1531 | "name": "Volker Dusch", 1532 | "email": "github@wallbash.com" 1533 | }, 1534 | { 1535 | "name": "Adam Harvey", 1536 | "email": "aharvey@php.net" 1537 | }, 1538 | { 1539 | "name": "Bernhard Schussek", 1540 | "email": "bschussek@gmail.com" 1541 | } 1542 | ], 1543 | "description": "Provides the functionality to export PHP variables for visualization", 1544 | "homepage": "https://www.github.com/sebastianbergmann/exporter", 1545 | "keywords": [ 1546 | "export", 1547 | "exporter" 1548 | ], 1549 | "support": { 1550 | "issues": "https://github.com/sebastianbergmann/exporter/issues", 1551 | "security": "https://github.com/sebastianbergmann/exporter/security/policy", 1552 | "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" 1553 | }, 1554 | "funding": [ 1555 | { 1556 | "url": "https://github.com/sebastianbergmann", 1557 | "type": "github" 1558 | } 1559 | ], 1560 | "time": "2024-03-02T07:17:12+00:00" 1561 | }, 1562 | { 1563 | "name": "sebastian/global-state", 1564 | "version": "6.0.2", 1565 | "source": { 1566 | "type": "git", 1567 | "url": "https://github.com/sebastianbergmann/global-state.git", 1568 | "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" 1569 | }, 1570 | "dist": { 1571 | "type": "zip", 1572 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", 1573 | "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", 1574 | "shasum": "" 1575 | }, 1576 | "require": { 1577 | "php": ">=8.1", 1578 | "sebastian/object-reflector": "^3.0", 1579 | "sebastian/recursion-context": "^5.0" 1580 | }, 1581 | "require-dev": { 1582 | "ext-dom": "*", 1583 | "phpunit/phpunit": "^10.0" 1584 | }, 1585 | "type": "library", 1586 | "extra": { 1587 | "branch-alias": { 1588 | "dev-main": "6.0-dev" 1589 | } 1590 | }, 1591 | "autoload": { 1592 | "classmap": [ 1593 | "src/" 1594 | ] 1595 | }, 1596 | "notification-url": "https://packagist.org/downloads/", 1597 | "license": [ 1598 | "BSD-3-Clause" 1599 | ], 1600 | "authors": [ 1601 | { 1602 | "name": "Sebastian Bergmann", 1603 | "email": "sebastian@phpunit.de" 1604 | } 1605 | ], 1606 | "description": "Snapshotting of global state", 1607 | "homepage": "https://www.github.com/sebastianbergmann/global-state", 1608 | "keywords": [ 1609 | "global state" 1610 | ], 1611 | "support": { 1612 | "issues": "https://github.com/sebastianbergmann/global-state/issues", 1613 | "security": "https://github.com/sebastianbergmann/global-state/security/policy", 1614 | "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" 1615 | }, 1616 | "funding": [ 1617 | { 1618 | "url": "https://github.com/sebastianbergmann", 1619 | "type": "github" 1620 | } 1621 | ], 1622 | "time": "2024-03-02T07:19:19+00:00" 1623 | }, 1624 | { 1625 | "name": "sebastian/lines-of-code", 1626 | "version": "2.0.2", 1627 | "source": { 1628 | "type": "git", 1629 | "url": "https://github.com/sebastianbergmann/lines-of-code.git", 1630 | "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" 1631 | }, 1632 | "dist": { 1633 | "type": "zip", 1634 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", 1635 | "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", 1636 | "shasum": "" 1637 | }, 1638 | "require": { 1639 | "nikic/php-parser": "^4.18 || ^5.0", 1640 | "php": ">=8.1" 1641 | }, 1642 | "require-dev": { 1643 | "phpunit/phpunit": "^10.0" 1644 | }, 1645 | "type": "library", 1646 | "extra": { 1647 | "branch-alias": { 1648 | "dev-main": "2.0-dev" 1649 | } 1650 | }, 1651 | "autoload": { 1652 | "classmap": [ 1653 | "src/" 1654 | ] 1655 | }, 1656 | "notification-url": "https://packagist.org/downloads/", 1657 | "license": [ 1658 | "BSD-3-Clause" 1659 | ], 1660 | "authors": [ 1661 | { 1662 | "name": "Sebastian Bergmann", 1663 | "email": "sebastian@phpunit.de", 1664 | "role": "lead" 1665 | } 1666 | ], 1667 | "description": "Library for counting the lines of code in PHP source code", 1668 | "homepage": "https://github.com/sebastianbergmann/lines-of-code", 1669 | "support": { 1670 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", 1671 | "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", 1672 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" 1673 | }, 1674 | "funding": [ 1675 | { 1676 | "url": "https://github.com/sebastianbergmann", 1677 | "type": "github" 1678 | } 1679 | ], 1680 | "time": "2023-12-21T08:38:20+00:00" 1681 | }, 1682 | { 1683 | "name": "sebastian/object-enumerator", 1684 | "version": "5.0.0", 1685 | "source": { 1686 | "type": "git", 1687 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1688 | "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" 1689 | }, 1690 | "dist": { 1691 | "type": "zip", 1692 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", 1693 | "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", 1694 | "shasum": "" 1695 | }, 1696 | "require": { 1697 | "php": ">=8.1", 1698 | "sebastian/object-reflector": "^3.0", 1699 | "sebastian/recursion-context": "^5.0" 1700 | }, 1701 | "require-dev": { 1702 | "phpunit/phpunit": "^10.0" 1703 | }, 1704 | "type": "library", 1705 | "extra": { 1706 | "branch-alias": { 1707 | "dev-main": "5.0-dev" 1708 | } 1709 | }, 1710 | "autoload": { 1711 | "classmap": [ 1712 | "src/" 1713 | ] 1714 | }, 1715 | "notification-url": "https://packagist.org/downloads/", 1716 | "license": [ 1717 | "BSD-3-Clause" 1718 | ], 1719 | "authors": [ 1720 | { 1721 | "name": "Sebastian Bergmann", 1722 | "email": "sebastian@phpunit.de" 1723 | } 1724 | ], 1725 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1726 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1727 | "support": { 1728 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", 1729 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" 1730 | }, 1731 | "funding": [ 1732 | { 1733 | "url": "https://github.com/sebastianbergmann", 1734 | "type": "github" 1735 | } 1736 | ], 1737 | "time": "2023-02-03T07:08:32+00:00" 1738 | }, 1739 | { 1740 | "name": "sebastian/object-reflector", 1741 | "version": "3.0.0", 1742 | "source": { 1743 | "type": "git", 1744 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1745 | "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" 1746 | }, 1747 | "dist": { 1748 | "type": "zip", 1749 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", 1750 | "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", 1751 | "shasum": "" 1752 | }, 1753 | "require": { 1754 | "php": ">=8.1" 1755 | }, 1756 | "require-dev": { 1757 | "phpunit/phpunit": "^10.0" 1758 | }, 1759 | "type": "library", 1760 | "extra": { 1761 | "branch-alias": { 1762 | "dev-main": "3.0-dev" 1763 | } 1764 | }, 1765 | "autoload": { 1766 | "classmap": [ 1767 | "src/" 1768 | ] 1769 | }, 1770 | "notification-url": "https://packagist.org/downloads/", 1771 | "license": [ 1772 | "BSD-3-Clause" 1773 | ], 1774 | "authors": [ 1775 | { 1776 | "name": "Sebastian Bergmann", 1777 | "email": "sebastian@phpunit.de" 1778 | } 1779 | ], 1780 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1781 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1782 | "support": { 1783 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues", 1784 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" 1785 | }, 1786 | "funding": [ 1787 | { 1788 | "url": "https://github.com/sebastianbergmann", 1789 | "type": "github" 1790 | } 1791 | ], 1792 | "time": "2023-02-03T07:06:18+00:00" 1793 | }, 1794 | { 1795 | "name": "sebastian/recursion-context", 1796 | "version": "5.0.0", 1797 | "source": { 1798 | "type": "git", 1799 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1800 | "reference": "05909fb5bc7df4c52992396d0116aed689f93712" 1801 | }, 1802 | "dist": { 1803 | "type": "zip", 1804 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", 1805 | "reference": "05909fb5bc7df4c52992396d0116aed689f93712", 1806 | "shasum": "" 1807 | }, 1808 | "require": { 1809 | "php": ">=8.1" 1810 | }, 1811 | "require-dev": { 1812 | "phpunit/phpunit": "^10.0" 1813 | }, 1814 | "type": "library", 1815 | "extra": { 1816 | "branch-alias": { 1817 | "dev-main": "5.0-dev" 1818 | } 1819 | }, 1820 | "autoload": { 1821 | "classmap": [ 1822 | "src/" 1823 | ] 1824 | }, 1825 | "notification-url": "https://packagist.org/downloads/", 1826 | "license": [ 1827 | "BSD-3-Clause" 1828 | ], 1829 | "authors": [ 1830 | { 1831 | "name": "Sebastian Bergmann", 1832 | "email": "sebastian@phpunit.de" 1833 | }, 1834 | { 1835 | "name": "Jeff Welch", 1836 | "email": "whatthejeff@gmail.com" 1837 | }, 1838 | { 1839 | "name": "Adam Harvey", 1840 | "email": "aharvey@php.net" 1841 | } 1842 | ], 1843 | "description": "Provides functionality to recursively process PHP variables", 1844 | "homepage": "https://github.com/sebastianbergmann/recursion-context", 1845 | "support": { 1846 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 1847 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" 1848 | }, 1849 | "funding": [ 1850 | { 1851 | "url": "https://github.com/sebastianbergmann", 1852 | "type": "github" 1853 | } 1854 | ], 1855 | "time": "2023-02-03T07:05:40+00:00" 1856 | }, 1857 | { 1858 | "name": "sebastian/type", 1859 | "version": "4.0.0", 1860 | "source": { 1861 | "type": "git", 1862 | "url": "https://github.com/sebastianbergmann/type.git", 1863 | "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" 1864 | }, 1865 | "dist": { 1866 | "type": "zip", 1867 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", 1868 | "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", 1869 | "shasum": "" 1870 | }, 1871 | "require": { 1872 | "php": ">=8.1" 1873 | }, 1874 | "require-dev": { 1875 | "phpunit/phpunit": "^10.0" 1876 | }, 1877 | "type": "library", 1878 | "extra": { 1879 | "branch-alias": { 1880 | "dev-main": "4.0-dev" 1881 | } 1882 | }, 1883 | "autoload": { 1884 | "classmap": [ 1885 | "src/" 1886 | ] 1887 | }, 1888 | "notification-url": "https://packagist.org/downloads/", 1889 | "license": [ 1890 | "BSD-3-Clause" 1891 | ], 1892 | "authors": [ 1893 | { 1894 | "name": "Sebastian Bergmann", 1895 | "email": "sebastian@phpunit.de", 1896 | "role": "lead" 1897 | } 1898 | ], 1899 | "description": "Collection of value objects that represent the types of the PHP type system", 1900 | "homepage": "https://github.com/sebastianbergmann/type", 1901 | "support": { 1902 | "issues": "https://github.com/sebastianbergmann/type/issues", 1903 | "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" 1904 | }, 1905 | "funding": [ 1906 | { 1907 | "url": "https://github.com/sebastianbergmann", 1908 | "type": "github" 1909 | } 1910 | ], 1911 | "time": "2023-02-03T07:10:45+00:00" 1912 | }, 1913 | { 1914 | "name": "sebastian/version", 1915 | "version": "4.0.1", 1916 | "source": { 1917 | "type": "git", 1918 | "url": "https://github.com/sebastianbergmann/version.git", 1919 | "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" 1920 | }, 1921 | "dist": { 1922 | "type": "zip", 1923 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", 1924 | "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", 1925 | "shasum": "" 1926 | }, 1927 | "require": { 1928 | "php": ">=8.1" 1929 | }, 1930 | "type": "library", 1931 | "extra": { 1932 | "branch-alias": { 1933 | "dev-main": "4.0-dev" 1934 | } 1935 | }, 1936 | "autoload": { 1937 | "classmap": [ 1938 | "src/" 1939 | ] 1940 | }, 1941 | "notification-url": "https://packagist.org/downloads/", 1942 | "license": [ 1943 | "BSD-3-Clause" 1944 | ], 1945 | "authors": [ 1946 | { 1947 | "name": "Sebastian Bergmann", 1948 | "email": "sebastian@phpunit.de", 1949 | "role": "lead" 1950 | } 1951 | ], 1952 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1953 | "homepage": "https://github.com/sebastianbergmann/version", 1954 | "support": { 1955 | "issues": "https://github.com/sebastianbergmann/version/issues", 1956 | "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" 1957 | }, 1958 | "funding": [ 1959 | { 1960 | "url": "https://github.com/sebastianbergmann", 1961 | "type": "github" 1962 | } 1963 | ], 1964 | "time": "2023-02-07T11:34:05+00:00" 1965 | }, 1966 | { 1967 | "name": "theseer/tokenizer", 1968 | "version": "1.2.3", 1969 | "source": { 1970 | "type": "git", 1971 | "url": "https://github.com/theseer/tokenizer.git", 1972 | "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" 1973 | }, 1974 | "dist": { 1975 | "type": "zip", 1976 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", 1977 | "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", 1978 | "shasum": "" 1979 | }, 1980 | "require": { 1981 | "ext-dom": "*", 1982 | "ext-tokenizer": "*", 1983 | "ext-xmlwriter": "*", 1984 | "php": "^7.2 || ^8.0" 1985 | }, 1986 | "type": "library", 1987 | "autoload": { 1988 | "classmap": [ 1989 | "src/" 1990 | ] 1991 | }, 1992 | "notification-url": "https://packagist.org/downloads/", 1993 | "license": [ 1994 | "BSD-3-Clause" 1995 | ], 1996 | "authors": [ 1997 | { 1998 | "name": "Arne Blankerts", 1999 | "email": "arne@blankerts.de", 2000 | "role": "Developer" 2001 | } 2002 | ], 2003 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 2004 | "support": { 2005 | "issues": "https://github.com/theseer/tokenizer/issues", 2006 | "source": "https://github.com/theseer/tokenizer/tree/1.2.3" 2007 | }, 2008 | "funding": [ 2009 | { 2010 | "url": "https://github.com/theseer", 2011 | "type": "github" 2012 | } 2013 | ], 2014 | "time": "2024-03-03T12:36:25+00:00" 2015 | } 2016 | ], 2017 | "aliases": [], 2018 | "minimum-stability": "stable", 2019 | "stability-flags": {}, 2020 | "prefer-stable": false, 2021 | "prefer-lowest": false, 2022 | "platform": { 2023 | "php": "^8.1" 2024 | }, 2025 | "platform-dev": {}, 2026 | "plugin-api-version": "2.6.0" 2027 | } 2028 | --------------------------------------------------------------------------------