Skip to content

Added presenter mapper #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/Application/IPresenterMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/

namespace Nette\Application;

interface IPresenterMapper
{
/**
* Formats presenter class name from its name.
* @param string
* @return string
*/
function formatPresenterClass($presenter);

/**
* Formats presenter name from class name.
* @param string
* @return string
*/
function unformatPresenterClass($class);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing newline

68 changes: 7 additions & 61 deletions src/Application/PresenterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,20 @@ class PresenterFactory extends Nette\Object implements IPresenterFactory
/** @var bool */
public $caseSensitive = FALSE;

/** @var array[] of module => splited mask */
private $mapping = array(
'*' => array('', '*Module\\', '*Presenter'),
'Nette' => array('NetteModule\\', '*\\', '*Presenter'),
);

/** @var array */
private $cache = array();

/** @var Nette\DI\Container */
private $container;

/** @var \Nette\Application\IPresenterMapper */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for FQCN.

private $presenterMapper;


public function __construct(Nette\DI\Container $container)
public function __construct(Nette\DI\Container $container, IPresenterMapper $presenterMapper)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd swap these params.

{
$this->container = $container;
$this->presenterMapper = $presenterMapper;
}


Expand Down Expand Up @@ -78,7 +76,7 @@ public function getPresenterClass(& $name)
throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");
}

$class = $this->formatPresenterClass($name);
$class = $this->presenterMapper->formatPresenterClass($name);
if (!class_exists($class)) {
throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found.");
}
Expand All @@ -93,7 +91,7 @@ public function getPresenterClass(& $name)
}

// canonicalize presenter name
$realName = $this->unformatPresenterClass($class);
$realName = $this->presenterMapper->unformatPresenterClass($class);
if ($name !== $realName) {
if ($this->caseSensitive) {
throw new InvalidPresenterException("Cannot load presenter '$name', case mismatch. Real name is '$realName'.");
Expand All @@ -108,56 +106,4 @@ public function getPresenterClass(& $name)
return $class;
}


/**
* Sets mapping as pairs [module => mask]
* @return self
*/
public function setMapping(array $mapping)
{
foreach ($mapping as $module => $mask) {
if (!preg_match('#^\\\\?([\w\\\\]*\\\\)?(\w*\*\w*?\\\\)?([\w\\\\]*\*\w*)\z#', $mask, $m)) {
throw new Nette\InvalidStateException("Invalid mapping mask '$mask'.");
}
$this->mapping[$module] = array($m[1], $m[2] ?: '*Module\\', $m[3]);
}
return $this;
}


/**
* Formats presenter class name from its name.
* @param string
* @return string
*/
public function formatPresenterClass($presenter)
{
$parts = explode(':', $presenter);
$mapping = isset($parts[1], $this->mapping[$parts[0]])
? $this->mapping[array_shift($parts)]
: $this->mapping['*'];

while ($part = array_shift($parts)) {
$mapping[0] .= str_replace('*', $part, $mapping[$parts ? 1 : 2]);
}
return $mapping[0];
}


/**
* Formats presenter name from class name.
* @param string
* @return string
*/
public function unformatPresenterClass($class)
{
foreach ($this->mapping as $module => $mapping) {
$mapping = str_replace(array('\\', '*'), array('\\\\', '(\w+)'), $mapping);
if (preg_match("#^\\\\?$mapping[0]((?:$mapping[1])*)$mapping[2]\\z#i", $class, $matches)) {
return ($module === '*' ? '' : $module . ':')
. preg_replace("#$mapping[1]#iA", '$1:', $matches[1]) . $matches[3];
}
}
}

}
73 changes: 73 additions & 0 deletions src/Application/PresenterMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

/**
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/

namespace Nette\Application;

use Nette;


class PresenterMapper extends Nette\Object implements IPresenterMapper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd name it "DefaultPresenterMapper". Or even better, something noting the fact it handles multiple modules mapping.

{
/** @var array[] of module => splited mask */
private $mapping = array(
'*' => array('', '*Module\\', '*Presenter'),
'Nette' => array('NetteModule\\', '*\\', '*Presenter'),
);


/**
* Sets mapping as pairs [module => mask]
* @return self
*/
public function setMapping(array $mapping)
{
foreach ($mapping as $module => $mask) {
if (!preg_match('#^\\\\?([\w\\\\]*\\\\)?(\w*\*\w*?\\\\)?([\w\\\\]*\*\w*)\z#', $mask, $m)) {
throw new Nette\InvalidStateException("Invalid mapping mask '$mask'.");
}
$this->mapping[$module] = array($m[1], $m[2] ?: '*Module\\', $m[3]);
}
return $this;
}


/**
* Formats presenter class name from its name.
* @param string
* @return string
*/
public function formatPresenterClass($presenter)
{
$parts = explode(':', $presenter);
$mapping = isset($parts[1], $this->mapping[$parts[0]])
? $this->mapping[array_shift($parts)]
: $this->mapping['*'];

while ($part = array_shift($parts)) {
$mapping[0] .= str_replace('*', $part, $mapping[$parts ? 1 : 2]);
}
return $mapping[0];
}


/**
* Formats presenter name from class name.
* @param string
* @return string
*/
public function unformatPresenterClass($class)
{
foreach ($this->mapping as $module => $mapping) {
$mapping = str_replace(array('\\', '*'), array('\\\\', '(\w+)'), $mapping);
if (preg_match("#^\\\\?$mapping[0]((?:$mapping[1])*)$mapping[2]\\z#i", $class, $matches)) {
return ($module === '*' ? '' : $module . ':')
. preg_replace("#$mapping[1]#iA", '$1:', $matches[1]) . $matches[3];
}
}
}

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline.

Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
* Test: Nette\Application\PresenterFactory.
*/

use Nette\Application\PresenterFactory,
use Nette\Application\PresenterMapper,
Tester\Assert;


require __DIR__ . '/../bootstrap.php';


$factory = new PresenterFactory(new Nette\DI\Container);
$factory = new PresenterMapper;

test(function() use ($factory) {
$factory->setMapping(array(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
* Test: Nette\Application\PresenterFactory.
*/

use Nette\Application\PresenterFactory,
use Nette\Application\PresenterMapper,
Tester\Assert;


require __DIR__ . '/../bootstrap.php';


test(function() {
$factory = new PresenterFactory(new Nette\DI\Container);
$factory = new PresenterMapper;

$factory->setMapping(array(
'Foo2' => 'App2\*\*Presenter',
Expand All @@ -35,7 +35,7 @@ test(function() {


test(function() {
$factory = new PresenterFactory(new Nette\DI\Container);
$factory = new PresenterMapper;

$factory->setMapping(array(
'Foo2' => 'App2\*Presenter',
Expand Down