Skip to content

Commit

Permalink
Added magic elevation method
Browse files Browse the repository at this point in the history
  • Loading branch information
jkphl committed Jul 3, 2017
1 parent 2c53b78 commit 18fe14f
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -2,7 +2,7 @@

[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Scrutinizer Code Quality][scrutinizer-image]][scrutinizer-url] [![Code Climate][codeclimate-image]][codeclimate-url] [![Documentation Status][readthedocs-image]][readthedocs-url] [![Clear architecture][clear-architecture-image]][clear-architecture-url]

> Elevator pattern implementation for PHP projects
> Elevator pattern — type casting of user defined objects in PHP
## Documentation

Expand Down
53 changes: 52 additions & 1 deletion doc/index.md
@@ -1,6 +1,8 @@
# jkphl/elevator

> Elevator pattern implementation for PHP projects
[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Scrutinizer Code Quality][scrutinizer-image]][scrutinizer-url] [![Code Climate][codeclimate-image]][codeclimate-url] [![Documentation Status][readthedocs-image]][readthedocs-url] [![Clear architecture][clear-architecture-image]][clear-architecture-url]

> Elevator pattern — type casting of user defined objects in PHP
PHP offers no built-in way to cast a user-defined object to another class — probably for good reasons. There are some dirty hacks to achieve similar effects, but in general these are considered harmful.

Expand Down Expand Up @@ -74,3 +76,52 @@ $object = new MyClass();
/** @var MySubclass $elevatedObject */
$elevatedObject = Elevator::elevate($object, MySubclass::class, 'some', 'values');
```

## Installation

This library requires PHP >=5.6 or later. I recommend using the latest available version of PHP as a matter of principle. It has no userland dependencies.

## Dependencies

![Composer dependency graph](https://rawgit.com/jkphl/elevator/master/doc/dependencies.svg)

## Quality

To run the unit tests at the command line, issue `composer install` and then `phpunit` at the package root. This requires [Composer](http://getcomposer.org/) to be available as `composer`, and [PHPUnit](http://phpunit.de/manual/) to be available as `phpunit`.

This library attempts to comply with [PSR-1][], [PSR-2][], and [PSR-4][]. If you notice compliance oversights, please send a patch via pull request.

## Contributing

Found a bug or have a feature request? [Please have a look at the known issues](https://github.com/jkphl/elevator/issues) first and open a new issue if necessary. Please see [contributing](../CONTRIBUTING.md) and [conduct](../CONDUCT.md) for details.

## Security

If you discover any security related issues, please email joschi@kuphal.net instead of using the issue tracker.

## Credits

- [Joschi Kuphal][author-url]
- [All Contributors](../../contributors)

## License

Copyright © 2017 [Joschi Kuphal][author-url] / joschi@kuphal.net. Licensed under the terms of the [MIT license](../LICENSE).


[travis-image]: https://secure.travis-ci.org/jkphl/elevator.svg
[travis-url]: https://travis-ci.org/jkphl/elevator
[coveralls-image]: https://coveralls.io/repos/jkphl/elevator/badge.svg?branch=master&service=github
[coveralls-url]: https://coveralls.io/github/jkphl/elevator?branch=master
[scrutinizer-image]: https://scrutinizer-ci.com/g/jkphl/elevator/badges/quality-score.png?b=master
[scrutinizer-url]: https://scrutinizer-ci.com/g/jkphl/elevator/?branch=master
[codeclimate-image]: https://lima.codeclimate.com/github/jkphl/elevator/badges/gpa.svg
[codeclimate-url]: https://lima.codeclimate.com/github/jkphl/elevator
[readthedocs-image]: https://readthedocs.org/projects/jkphl-elevator/badge/?version=latest
[readthedocs-url]: http://jkphl-elevator.readthedocs.io/en/latest/?badge=latest
[clear-architecture-image]: https://img.shields.io/badge/Clear%20Architecture-%E2%9C%94-brightgreen.svg
[clear-architecture-url]: https://github.com/jkphl/clear-architecture
[author-url]: https://jkphl.is
[PSR-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
[PSR-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
[PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
13 changes: 11 additions & 2 deletions src/Elevator/Application/ElevatorService.php
Expand Up @@ -38,6 +38,7 @@

use Jkphl\Elevator\Domain\ElevationMap;
use Jkphl\Elevator\Domain\Elevator;
use Jkphl\Elevator\Ports\ElevatorAwareInterface;

/**
* Elevator service
Expand Down Expand Up @@ -68,12 +69,20 @@ public function __construct($source)
* Elevate the source object to the given target class
*
* @param string $class Target class name
* @param array $args Elevation arguments
* @return object Elevated object
*/
public function elevate($class)
public function elevate($class, ...$args)
{
$elevator = new Elevator($this->source);
$elevationMap = new ElevationMap($this->source);
return $elevator->elevate(new \ReflectionClass($class), $elevationMap);
$elevated = $elevator->elevate(new \ReflectionClass($class), $elevationMap);

// Call the magic elevation method
if ($elevated instanceof ElevatorAwareInterface) {
$elevated->__elevate(...$args);
}

return $elevated;
}
}
5 changes: 3 additions & 2 deletions src/Elevator/Ports/Elevator.php
Expand Up @@ -51,11 +51,12 @@ class Elevator
*
* @param object $object Source object
* @param string $class Target class name
* @param array $args Elevation arguments
* @return object Elevated object
*/
public static function elevate($object, $class)
public static function elevate($object, $class, ...$args)
{
$elevatorService = new ElevatorService($object);
return $elevatorService->elevate($class);
return $elevatorService->elevate($class, ...$args);
}
}
22 changes: 21 additions & 1 deletion src/Elevator/Tests/Fixture/Elevated.php
Expand Up @@ -36,14 +36,22 @@

namespace Jkphl\Elevator\Tests\Fixture;

use Jkphl\Elevator\Ports\ElevatorAwareInterface;

/**
* Elevated test class
*
* @package Jkphl\Elevator
* @subpackage Jkphl\Elevator\Tests
*/
class Elevated extends Outer
class Elevated extends Outer implements ElevatorAwareInterface
{
/**
* Property modified by the pseudo-constructor
*
* @var string
*/
public $elevatedMagic = null;
/**
* Public property
*
Expand All @@ -62,4 +70,16 @@ class Elevated extends Outer
* @var string
*/
protected $elevatedProtected = 'elevated-protected';

/**
* Custom elevation pseudo constructor
*
* @param array ...$args Elevation arguments
*/
public function __elevate(...$args)
{
if (count($args)) {
$this->elevatedMagic = current($args);
}
}
}
14 changes: 14 additions & 0 deletions src/Elevator/Tests/Ports/ElevatorTest.php
Expand Up @@ -63,4 +63,18 @@ public function testElevator()
$this->assertEquals($random, $elevated->innerPublic);
$this->assertEquals('inner-private', $elevated->getInnerPrivate());
}

/**
* Test the __elevate() magic method
*/
public function testElevatorMagic()
{
$random = md5(rand());
$outer = new Outer();

/** @var Elevated $elevated */
$elevated = Elevator::elevate($outer, Elevated::class, $random);
$this->assertInstanceOf(Elevated::class, $elevated);
$this->assertEquals($random, $elevated->elevatedMagic);
}
}

0 comments on commit 18fe14f

Please sign in to comment.