Skip to content

Commit

Permalink
add composer function
Browse files Browse the repository at this point in the history
Add support Laravel compose function
  • Loading branch information
maxisoft-git committed May 31, 2015
1 parent 9bd014d commit c656c0d
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 27 deletions.
178 changes: 178 additions & 0 deletions src/Fenom/FenomFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Pafnuty\Fenom;

use Illuminate\Contracts\View\Factory as FactoryContract;
use Illuminate\Contracts\Container\Container;
use Illuminate\Foundation\Application;

/**
Expand All @@ -27,13 +28,36 @@ class FenomFactory implements FactoryContract
* */
private $fenom;

/**
* The event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;

/**
* The view composer events.
*
* @var array
*/
protected $composers = array();

/**
* The IoC container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;

/**
* @param \Illuminate\Foundation\Application $app
*/
public function __construct(Application $app)
{
$this->fenom = $app['fenom'];
$this->config = $app['config'];
$this->events = $app['events'];

}

/**
Expand All @@ -57,7 +81,26 @@ public function exists($path)

return true;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Contracts\Container\Container
*/
public function getContainer()
{
return $this->container;
}

/**
* Set the IoC container instance.
*
* @param \Illuminate\Contracts\Container\Container $container
* @return void
*/
public function setContainer(Container $container)
{
$this->container = $container;
}
/**
* Get the evaluated view contents for the given path.
*
Expand Down Expand Up @@ -118,6 +161,24 @@ public function render($view, $data)
return $this->fenom->fetch($view, $data);
}

/**
* Register multiple view composers via an array.
*
* @param array $composers
* @return array
*/
public function composers(array $composers)
{
$registered = array();

foreach ($composers as $callback => $views)
{
$registered = array_merge($registered, $this->composer($views, $callback));
}

return $registered;
}

/**
* Register a view composer event.
*
Expand All @@ -127,9 +188,125 @@ public function render($view, $data)
*
* @return array
*/

public function composer($views, $callback, $priority = null)
{
$composers = array();

foreach ((array) $views as $view)
{
$composers[] = $this->addViewEvent($view, $callback, 'composing: ', $priority);
}

return $composers;
}

protected function addViewEvent($view, $callback, $prefix = 'composing: ', $priority = null)
{
if ($callback instanceof Closure)
{
$this->addEventListener($prefix.$view, $callback, $priority);
return $callback;
}
elseif (is_string($callback))
{
return $this->addClassEvent($view, $callback, $prefix, $priority);
}
}

/**
* Register a class based view composer.
*
* @param string $view
* @param string $class
* @param string $prefix
* @param int|null $priority
* @return \Closure
*/
protected function addClassEvent($view, $class, $prefix, $priority = null)
{
$name = $prefix.$view;

// When registering a class based view "composer", we will simply resolve the
// classes from the application IoC container then call the compose method
// on the instance. This allows for convenient, testable view composers.
$callback = $this->buildClassEventCallback($class, $prefix);

$this->addEventListener($name, $callback, $priority);

return $callback;
}

/**
* Add a listener to the event dispatcher.
*
* @param string $name
* @param \Closure $callback
* @param int $priority
* @return void
*/
protected function addEventListener($name, $callback, $priority = null)
{
if (is_null($priority))
{
$this->events->listen($name, $callback);
}
else
{
$this->events->listen($name, $callback, $priority);
}
}

/**
* Build a class based container callback Closure.
*
* @param string $class
* @param string $prefix
* @return \Closure
*/
protected function buildClassEventCallback($class, $prefix)
{
list($class, $method) = $this->parseClassEvent($class, $prefix);

// Once we have the class and method name, we can build the Closure to resolve
// the instance out of the IoC container and call the method on it with the
// given arguments that are passed to the Closure as the composer's data.
return function() use ($class, $method)
{
$callable = array($this->container->make($class), $method);

return call_user_func_array($callable, func_get_args());
};
}

/**
* Parse a class based composer name.
*
* @param string $class
* @param string $prefix
* @return array
*/
protected function parseClassEvent($class, $prefix)
{
if (str_contains($class, '@'))
{
return explode('@', $class);
}

$method = str_contains($prefix, 'composing') ? 'compose' : 'create';

return array($class, $method);
}

/**
* Call the composer for a given view.
*
* @param \Illuminate\View\View $view
* @return void
*/
public function callComposer(FenomView $view)
{
$this->events->fire('composing: '.$view->getName(), array($view));
}

/**
Expand Down Expand Up @@ -158,4 +335,5 @@ public function addNamespace($namespace, $hints)

}


}
70 changes: 44 additions & 26 deletions src/Fenom/FenomView.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,52 +33,70 @@ class FenomView implements ViewContract
private $factory;


/**
* @param \Pafnuty\Fenom\FenomFactory $factory
* @param $view
* @param array $data
*/
public function __construct(FenomFactory $factory, $view, $data = [])
/**
* @param \Pafnuty\Fenom\FenomFactory $factory
* @param $view
* @param array $data
*/
public function __construct(FenomFactory $factory, $view, $data = [])
{
$this->factory = $factory;
$this->view = $view;
$this->data = $data;
}

/**
* @return mixed
*/
public function name()
/**
* Get the name of the view.
*
* @return string
*/
public function name()
{
return $this->getName();
}

/**
* Get the name of the view.
*
* @return string
*/
public function getName()
{
return $this->view;
}

/**
* @param array|string $key
* @param null $value
*
* @return $this
*/
public function with($key, $value = null)
/**
* @param array|string $key
* @param null $value
*
* @return $this
*/
public function with($key, $value = null)
{
$this->data[$key] = $value;
if (is_array($key)){
$this->data = array_merge($this->data, $key);
} else {
$this->data[$key] = $value;
}

return $this;
}

/**
* @return mixed
*/
public function __toString()
/**
* @return mixed
*/
public function __toString()
{
return $this->render();
}

/**
* @return mixed
*/
public function render()
/**
* @return mixed
*/
public function render()
{
$this->factory->callComposer($this);

return $this->factory->render($this->view, $this->data);
}

Expand Down
9 changes: 8 additions & 1 deletion src/Fenom/FenomViewServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,15 @@ public function register()
$this->publishes([$configPath => config_path('view-fenom.php')]);

$this->app->bind('view', function ($app) {
return new FenomFactory($app);
$env = new FenomFactory($app);

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

return $env;
});


}

/**
Expand Down

0 comments on commit c656c0d

Please sign in to comment.