Skip to content

Commit

Permalink
Modified the logic for passing an invalid key to the Decorator and
Browse files Browse the repository at this point in the history
functionality for automatically building decorators for associations.
  • Loading branch information
Joey Trapp committed Feb 19, 2012
1 parent 4628819 commit b259894
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 28 deletions.
6 changes: 2 additions & 4 deletions Controller/Component/DecoratorComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
* DecoratorComponent
*
* @uses Component
* @package
* @package Controller.Component
* @version $id$
* @copyright 1997-2005 The PHP Group
* @author Tobias Schlitt <toby@php.net>
* @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
* @author Joey Trapp <jtrapp07@gmail.com>
*/

require_once(App::pluginPath("Decorator") . "View" . DS . "Decorator" . DS . "DecoratorFactory.php");
Expand Down
3 changes: 2 additions & 1 deletion Test/Case/Controller/Component/DecoratorComponentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public function testBuildReturnsListOfTheSameSizeFromInvalidName() {
$d = $this->Decorator->build("NoExist", $data);
$this->assertEquals(2, count($d));
$this->assertEquals("Decorator", get_class($d[0]));
$this->assertEquals($this->data["DecoratorComponentTest"], $d[1]->raw("DecoratorComponentTest"));
$this->assertEmpty($d[0]->model);
$this->assertEquals(5, $d[0]->DecoratorComponentTest->id());
}

public function testBuildReturnsListOfTheSameSizeValidName() {
Expand Down
37 changes: 35 additions & 2 deletions Test/Case/View/Decorator/DecoratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,42 @@ public function testDecoratorCanImportDataForItsModelName() {
$this->assertEquals($this->data["DecoratorTest"], $d->model);
}

public function testDecoratorWillAssignAllDataIfNoMatch() {
public function testDecoratorWillNotAssignAllDataIfNoMatch() {
$d = new DecoratorTestCustomDecorator($this->data);
$this->assertEquals($this->data, $d->model);
$this->assertEmpty($d->model);
}

public function testDecoratorCanTakeASecondArgToDefineTheParseName() {
$d = new DecoratorTestCustomDecorator($this->data, "DecoratorTest");
$this->assertEquals("DecoratorTestCustomDecorator", get_class($d));
$this->assertEquals(5, $d->id());
}

public function testDecoratorWillAutoCreateSiblingObjects() {
$data = array(
"TestOne" => array("id" => 1, "content" => "Sample content"),
"TestTwo" => array("id" => 2, "content" => "Sample content")
);
$d = new Decorator($data, "TestOne");
$this->assertEquals(1, $d->id());
$this->assertEquals(2, $d->TestTwo->id());
$d = new Decorator($data, "TestTwo");
$this->assertEquals(2, $d->id());
$this->assertEquals(1, $d->TestOne->id());
}

public function testDecoratorWillAutoCreateNestedObjects() {
$data = array(
"TestOne" => array("id" => 1, "content" => "Sample content"),
"TestTwo" => array(
array("id" => 2, "content" => "Different content"),
array("id" => 3, "content" => "Something content")
)
);
$d = new Decorator($data, "TestOne");
$this->assertEquals(1, $d->id());
$this->assertEquals(2, count($d->TestTwo));
$this->assertEquals("Something content", $d->TestTwo[1]->content());
}

public function testDecoratorWillReturnDataFromUndefinedMethods() {
Expand Down
73 changes: 60 additions & 13 deletions View/Decorator/Decorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
/**
* Decorator
*
* @uses Object
* @package
* @package View.Decorator
* @version $id$
* @copyright 1997-2005 The PHP Group
* @author Tobias Schlitt <toby@php.net>
* @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
* @author Joey Trapp <jtrapp07@gmail.com>
*/

require_once(App::pluginPath("Decorator") . "View" . DS . "Decorator" . DS . "DecoratorFactory.php");

class Decorator {

/**
Expand All @@ -33,18 +32,15 @@ class Decorator {
* then calls the parseData method to parse the passed in array of data.
*
* @param array $data
* @param mixed $parse
* @access public
* @return void
*/
public function __construct($data = array(), $parse = true) {
if (!$this->name) {
$this->name = preg_replace("/Decorator$/", "", get_class($this));
}
if ($parse) {
$this->model = $this->parseData($data);
} else {
$this->model = $data;
}
$this->model = $this->parseData($data, $parse);
}

/**
Expand All @@ -53,19 +49,70 @@ public function __construct($data = array(), $parse = true) {
* parsing logic.
*
* @param array $data
* @param mixed $parse
* @access public
* @return array
*/
public function parseData($data = array()) {
public function parseData($data = array(), $parse = true) {
$ret = array();
if (array_key_exists($this->name, $data)) {
$ret = $data[$this->name];
$name = $this->name;
if (is_string($parse)) {
$name = $parse;
}
if ($parse) {
if (array_key_exists($name, $data)) {
$ret = $data[$name];
unset($data[$name]);
// Builds sibling associations
$this->_buildAssociations($data);
// Builds nested associations
$this->_buildAssociations($ret);
} else {
// Builds nested associations and returns array of non model key/values
$data = $this->_buildAssociations($data);
$ret = $data;
}
} else {
$ret = $data;
}
return $ret;
}

/**
* Takes an array of data loops over them. If any of the keys match a model
* name regex, then the value for that key is inspected. If the value is an
* array and they keys are numeric, then the DecoratorFactory::build() method
* is called. If the value is array and the keys are not numeric then the
* DecoratorFactory::create() method is called. The results of build() or
* create() are assigned to properties of the model name on this decorator.
* All keys that are used to create decorators are unset from the data and
* the data array is returned.
*
* @param mixed $data
* @access protected
* @return array
*/
protected function _buildAssociations($data) {
$keys = array_keys($data);
for ($i = 0; $i < count($keys); $i++) {
$key = $keys[$i];
$value = $data[$key];
if (
preg_match("/^[A-Z]{1}[a-zA-Z]+/", $key) &&
is_array($value) &&
!empty($value)
) {
if (preg_match("/[0-9]+/", key($value))) {
$this->{$key} = DecoratorFactory::build($key, $value, $key);
} else {
$this->{$key} = DecoratorFactory::create($key, $value, $key);
}
unset($data[$key]);
}
}
return $data;
}

/**
* By default this is available to return the raw value from the model
* array. The logic is in the _raw protected method so that the raw
Expand Down
8 changes: 4 additions & 4 deletions View/Decorator/DecoratorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
/**
* DecoratorFactory
*
* @package
* @package View.Decorator
* @version $id$
* @copyright 1997-2005 The PHP Group
* @author Tobias Schlitt <toby@php.net>
* @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
* @author Joey Trapp <jtrapp07@gmail.com>
*/

require_once(App::pluginPath("Decorator") . "View" . DS . "Decorator" . DS . "Decorator.php");
Expand All @@ -18,6 +16,7 @@ class DecoratorFactory {
*
* @param mixed $name
* @param array $data
* @param mixed $parse
* @static
* @access public
* @return void
Expand Down Expand Up @@ -46,6 +45,7 @@ public static function create($name, $data = array(), $parse = true) {
*
* @param mixed $name
* @param array $data
* @param mixed $parse
* @static
* @access public
* @return void
Expand Down
6 changes: 2 additions & 4 deletions View/Helper/DecoratorHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
* DecoratorHelper
*
* @uses AppHelper
* @package
* @package View.Helper
* @version $id$
* @copyright 1997-2005 The PHP Group
* @author Tobias Schlitt <toby@php.net>
* @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
* @author Joey Trapp <jtrapp07@gmail.com>
*/

require_once(App::pluginPath("Decorator") . "View" . DS . "Decorator" . DS . "DecoratorFactory.php");
Expand Down

0 comments on commit b259894

Please sign in to comment.