Skip to content

Commit

Permalink
Merge branch 'release/1.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
robclancy committed Jun 17, 2014
2 parents dd23780 + 7624dc6 commit 06d6e16
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 52 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
language: php

php:
- 5.3
php:
- 5.4

before_script:
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This library provides a simple class to help make a `Presenter` for your objects
Add `robclancy/presenter` to the "require" section of your `composer.json` file.

```json
"robclancy/presenter": "1.1.*"
"robclancy/presenter": "1.3.*"
```

Run `composer update` to get the latest version of the package.
Expand Down Expand Up @@ -55,7 +55,7 @@ Now presenters will automatically be created if using the <a href="#laravel-usag

## Usage

`Presenter` is a very simply class that overloads methods and variables so that you can add extra logic to your objects or arrays without adding view logic to areas like your models or controllers and also keeps any extra logic our of your views.
`Presenter` is a very simple class that overloads methods and variables so that you can add extra logic to your objects or arrays without adding view logic to areas like your models or controllers and also keeps any extra logic out of your views.

### General Usage

Expand All @@ -72,7 +72,7 @@ class UserPresenter extends Robbo\Presenter\Presenter {
}
```

Now our view should receive an instance of this presenter which would be created with something like `$user = new PresenterUser(new User);`. If we want to link to the users page all we have to do is call `$user->url()`. Now you have good separation of logic and an easy little class you can modify to add properties to your `User` in all areas.
Now our view should receive an instance of this presenter which would be created with something like `$user = new UserPresenter(new User);`. If we want to link to the users page all we have to do is call `$user->url()`. Now you have good separation of logic and an easy little class you can modify to add properties to your `User` in all areas.
However you might not want to be calling methods like this, it could be inconsistant with what you are doing or you might want the code to look a little cleaner. That is where methods with the `present` prefix come in. All we do is update the presenter to the following.

```php
Expand Down Expand Up @@ -263,6 +263,11 @@ And that is all there is to it. You can easily automate the creation of presente

## Change Log

#### 1.3.0
- updated to work with `laravel 4.2.x`, to use in `4.1.x` stay on version `1.2.*`
- moved to PSR-4 and now PHP 5.4+
- small refactor and check `isset` again 'present' methods, thanks [BenConstable](https://github.com/robclancy/presenter/pull/25)

#### 1.2.0
- presenters can now be nested, thanks [alexwhitman](https://github.com/robclancy/presenter/pull/10)
- added support for using Laravel's `View::with(array here)`, thanks [skovachev](https://github.com/robclancy/presenter/pull/14)
Expand Down
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@
}
],
"require": {
"php": ">=5.3.0"
"php": ">=5.4.0"
},
"require-dev": {
"mockery/mockery": "0.7.2",
"illuminate/view": "4.0.*",
"illuminate/view": "4.2.*",
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {
"Robbo\\Presenter": "src/"
"psr-4": {
"Robbo\\Presenter\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
"dev-master": "1.3-dev"
}
},
"minimum-stability": "stable"
Expand Down
File renamed without changes.
File renamed without changes.
40 changes: 31 additions & 9 deletions src/Robbo/Presenter/Presenter.php → src/Presenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected function __getDecorator()

/**
* This is so you can extend the decorator and inject it into the presenter at the class level so the
* new decorator will be used for nested presenters. Method name should be "setDecorator" however
* new decorator will be used for nested presenters. Method name should be "setDecorator" however
* like above I want to make conflicts less likely.
*
* @param \Robbo\Presenter\Decorator
Expand All @@ -58,7 +58,7 @@ public static function setExtendedDecorator(Decorator $decorator)

/**
* Get the object we are wrapping.
*
*
* @return mixed
*/
public function getObject()
Expand All @@ -75,12 +75,15 @@ public function getObject()
public function offsetExists($offset)
{
// We only check isset on the array, if it is an object we return true as the object could be overloaded
if (is_array($this->object))
if ( ! is_array($this->object)) return true;

if ($method = $this->getPresenterMethodFromVariable($offset))
{
return isset($this->object[$offset]);
$result = $this->$method();
return isset($result);
}

return true;
return isset($this->object[$offset]);
}

/**
Expand Down Expand Up @@ -130,15 +133,14 @@ public function offsetUnset($offset)
}

/**
* Pass any unknown varible calls to present{$variable} or fall through to the injected object.
* Pass any unknown variable calls to present{$variable} or fall through to the injected object.
*
* @param string $var
* @return mixed
*/
public function __get($var)
{
$method = 'present'.str_replace(' ', '', ucwords(str_replace(array('-', '_'), ' ', $var)));
if (method_exists($this, $method))
if ($method = $this->getPresenterMethodFromVariable($var))
{
return $this->$method();
}
Expand Down Expand Up @@ -173,6 +175,12 @@ public function __call($method, $arguments)
*/
public function __isset($name)
{
if ($method = $this->getPresenterMethodFromVariable($name))
{
$result = $this->$method();
return isset($result);
}

if (is_array($this->object))
{
return isset($this->object[$name]);
Expand All @@ -182,7 +190,7 @@ public function __isset($name)
}

/**
* Allow to unset a variable through the persenter
* Allow to unset a variable through the presenter
*
* @param string $name
*/
Expand All @@ -197,4 +205,18 @@ public function __unset($name)
unset($this->object->$name);
}

/**
* Fetch the 'present' method name for the given variable.
*
* @param string $variable
* @return string|null
*/
protected function getPresenterMethodFromVariable($variable)
{
$method = 'present'.str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $variable)));
if (method_exists($this, $method))
{
return $method;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function register()
{
$this->registerDecorator();

$this->registerEnvironment();
$this->registerFactory();
}

/**
Expand All @@ -56,31 +56,31 @@ public function registerDecorator()
/**
* Copied from the view service provider...
*
* Register the view environment.
* Register the view factory.
*
* @return void
*/
public function registerEnvironment()
public function registerFactory()
{
$this->app['view'] = $this->app->share(function($app)
{
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// factory. The resolver will be used by a factory to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];

$finder = $app['view.finder'];

$env = new View\Environment($resolver, $finder, $app['events'], $app['presenter.decorator']);
$factory = new View\Factory($resolver, $finder, $app['events'], $app['presenter.decorator']);

// We will also set the container instance on this view environment since the
// We will also set the container instance on this view factory since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$env->setContainer($app);
$factory->setContainer($app);

$env->share('app', $app);
$factory->share('app', $app);

return $env;
return $factory;
});
}

Expand All @@ -91,7 +91,7 @@ public function registerEnvironment()
*/
public function provides()
{
return array();
return [];
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
use Illuminate\View\ViewFinderInterface;
use Robbo\Presenter\PresentableInterface;
use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Environment as BaseEnvironment;
use Illuminate\View\Factory as BaseFactory;

class Environment extends BaseEnvironment {
class Factory extends BaseFactory {

/**
* Used for "decorating" objects to have presenters.
Expand All @@ -18,7 +18,7 @@ class Environment extends BaseEnvironment {
protected $presenterDecorator;

/**
* Create a new view environment instance.
* Create a new view factory instance.
*
* @param \Illuminate\View\Engines\EngineResolver $engines
* @param \Illuminate\View\ViewFinderInterface $finder
Expand All @@ -41,7 +41,7 @@ public function __construct(EngineResolver $engines, ViewFinderInterface $finder
* @param array $mergeData
* @return Illuminate\View\View
*/
public function make($view, $data = array(), $mergeData = array())
public function make($view, $data = [], $mergeData = [])
{
$path = $this->finder->find($view);

Expand All @@ -51,7 +51,7 @@ public function make($view, $data = array(), $mergeData = array())
}

/**
* Add a piece of shared data to the environment.
* Add a piece of shared data to the factory.
*
* @param string $key
* @param mixed $value
Expand Down
4 changes: 2 additions & 2 deletions src/Robbo/Presenter/View/View.php → src/View/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public function with($key, $value = null)
{
if (is_array($key))
{
return parent::with($this->environment->decorate($key));
return parent::with($this->factory->decorate($key));
}

return parent::with($key, $this->environment->decorate($value));
return parent::with($key, $this->factory->decorate($value));
}
}
10 changes: 10 additions & 0 deletions tests/PresenterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,21 @@ public function testArrayIsset()

$this->assertTrue(isset($presenter['testVar']));
$this->assertFalse(isset($presenter['unsetVar']));
$this->assertTrue(isset($presenter['awesome']));

$presenter = new PresenterStub(new InjectStub);
$this->assertTrue(isset($presenter['unsetVar']));
}

public function testObjectIsset()
{
$presenter = new PresenterStub(new InjectStub);

$this->assertTrue(isset($presenter->testVar));
$this->assertTrue(isset($presenter->awesome));
$this->assertFalse(isset($presenter->unsetVar));
}

public function testArraySet()
{
$presenter = new PresenterStub(array('testVar' => 'testvar'));
Expand Down
24 changes: 12 additions & 12 deletions tests/ViewEnvironmentTest.php → tests/ViewFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
use Robbo\Presenter\Decorator;
use Robbo\Presenter\View\View;
use Illuminate\Support\Collection;
use Robbo\Presenter\View\Environment;
use Robbo\Presenter\View\Factory;
use Robbo\Presenter\PresentableInterface;

class ViewEnvironmentTest extends PHPUnit_Framework_TestCase {
class ViewFactoryTest extends PHPUnit_Framework_TestCase {

public function tearDown()
{
Expand All @@ -25,10 +25,10 @@ public function testMakeView()
))
);

$env = $this->getEnvironment();
$env->finder->shouldReceive('find')->once()->andReturn('test');
$factory = $this->getFactory();
$factory->finder->shouldReceive('find')->once()->andReturn('test');

$view = $env->make('test', $data);
$view = $factory->make('test', $data);

$this->assertInstanceOf('Robbo\Presenter\View\View', $view);
$this->assertSame($view['meh'], $data['meh']);
Expand All @@ -38,9 +38,9 @@ public function testMakeView()
$this->assertInstanceOf('Robbo\Presenter\Presenter', $view['collection']['presentable']);
}

protected function getEnvironment()
protected function getFactory()
{
return new EnvironmentStub(
return new FactoryStub(
m::mock('Illuminate\View\Engines\EngineResolver'),
m::mock('Illuminate\View\ViewFinderInterface'),
m::mock('Illuminate\Events\Dispatcher'),
Expand All @@ -49,11 +49,11 @@ protected function getEnvironment()
}
}

class EnvironmentStub extends Environment {
class FactoryStub extends Factory {

public $finder;

protected function getEngineFromPath($path)
public function getEngineFromPath($path)
{
return m::mock('Illuminate\View\Engines\EngineInterface');
}
Expand All @@ -75,16 +75,16 @@ public function getPresentableObject()

public function getPresenter()
{
return new EnvPresenterStub($this);
return new FactoryPresenterStub($this);
}
}

class SecondPresentableStub implements PresentableInterface {

public function getPresenter()
{
return new EnvPresenterStub($this);
return new FactoryPresenterStub($this);
}
}

class EnvPresenterStub extends Presenter {}
class FactoryPresenterStub extends Presenter {}
Loading

0 comments on commit 06d6e16

Please sign in to comment.