Skip to content

Commit

Permalink
Fix setting model attribute with setter to use setter (Fixes 11286)
Browse files Browse the repository at this point in the history
  • Loading branch information
nsossonko committed Feb 12, 2016
1 parent 8d99437 commit 6d17755
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
- Added `Phalcon\Dispatcher::hasParam()`.
- `Phalcon\Cli\Console` and `Phalcon\Mvc\Application` now inherit `Phalcon\Application`.
- Fixed `afterFetch` event not being sent to behaviors
- Fixed issue with Model::__set that was setting hidden attributes directly instead of calling setters [#11286](https://github.com/phalcon/cphalcon/issues/11286)

# [2.0.10](https://github.com/phalcon/cphalcon/releases/tag/phalcon-v2.0.10) (2015-XX-XX)
- ORM: Added support for DATE columns in Oracle
Expand Down
11 changes: 10 additions & 1 deletion phalcon/mvc/model.zep
Original file line number Diff line number Diff line change
Expand Up @@ -4101,7 +4101,7 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface
public function __set(string property, value)
{
var lowerProperty, related, modelName, manager, lowerKey,
relation, referencedModel, key, item, dirtyState;
relation, referencedModel, key, item, dirtyState, method;

/**
* Values are probably relationships if they are objects
Expand Down Expand Up @@ -4154,6 +4154,15 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface
return value;
}

/**
* Check if the property has setters
*/
let method = "set" . camelize(property);

if method_exists(this, method) {
return this->{method}(value);
}

/**
* Fallback assigning the value to the instance
*/
Expand Down
114 changes: 114 additions & 0 deletions unit-tests/ModelsGetterSetterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

/*
+------------------------------------------------------------------------+
| Phalcon Framework |
+------------------------------------------------------------------------+
| Copyright (c) 2011-2016 Phalcon Team (http://www.phalconphp.com) |
+------------------------------------------------------------------------+
| This source file is subject to the New BSD License that is bundled |
| with this package in the file docs/LICENSE.txt. |
| |
| If you did not receive a copy of the license and are unable to |
| obtain it through the world-wide-web, please send an email |
| to license@phalconphp.com so we can send you a copy immediately. |
+------------------------------------------------------------------------+
| Authors: Nochum Sossonko |
+------------------------------------------------------------------------+
*/

class ModelsGetterSetterTest extends PHPUnit_Framework_TestCase
{

public function __construct()
{
spl_autoload_register(array($this, 'modelsAutoloader'));
}

public function __destruct()
{
spl_autoload_unregister(array($this, 'modelsAutoloader'));
}

public function modelsAutoloader($className)
{
$className = str_replace('\\', DIRECTORY_SEPARATOR, $className);
if (file_exists('unit-tests/models/' . $className . '.php')) {
require 'unit-tests/models/' . $className . '.php';
}
}

protected function _getDI()
{

Phalcon\DI::reset();

$di = new Phalcon\DI();

$di->set('modelsManager', function(){
return new Phalcon\Mvc\Model\Manager();
});

$di->set('modelsMetadata', function(){
return new Phalcon\Mvc\Model\Metadata\Memory();
});

return $di;
}

public function testModelsMysql()
{

$di = $this->_getDI();

require 'unit-tests/config.db.php';
if (empty($configMysql)) {
$this->markTestSkipped('Test skipped');
return;
}

$connection = new Phalcon\Db\Adapter\Pdo\Mysql($configMysql);

$di->set('db', $connection, true);

$this->_executeSetGet();
}

/*public function testModelsPostgresql()
{
$di = $this->_getDI();
$di->set('db', function(){
require 'unit-tests/config.db.php';
return new Phalcon\Db\Adapter\Pdo\Postgresql($configPostgresql);
}, true);
$this->_executeSetGet();
}
public function testModelsSqlite()
{
$di = $this->_getDI();
$di->set('db', function(){
require 'unit-tests/config.db.php';
return new Phalcon\Db\Adapter\Pdo\Sqlite($configSqlite);
}, true);
$this->_executeSetGet();
}*/

public function _executeSetGet()
{
$robot = Boutique\Robots::findFirst();
$testText = 'executeSetGet Test';
$robot->assign(array('text' => $testText));
$this->assertEquals($robot->text, $testText . $robot::setterEpilogue);
$this->assertEquals($robot->text, $robot->getText());
$testText = 'executeSetGet Test 2';
$robot->text = $testText;
$this->assertEquals($robot->text, $testText . $robot::setterEpilogue);
}
}
12 changes: 11 additions & 1 deletion unit-tests/models/Boutique/Robots.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
class Robots extends \Phalcon\Mvc\Model
{

const setterEpilogue = " setText";

/**
* @Primary
* @Identity
Expand Down Expand Up @@ -35,5 +37,13 @@ class Robots extends \Phalcon\Mvc\Model
/**
* @Column(type="text", nullable=false)
*/
public $text;
protected $text;

public function getText() {
return $this->text;
}

public function setText($value) {
return ($this->text = $value . self::setterEpilogue);
}
}
1 change: 1 addition & 0 deletions unit-tests/phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
<file>unit-tests/ModelsEventsTest.php</file>
<file>unit-tests/ModelsFindersTest.php</file>
<file>unit-tests/ModelsForeignKeysTest.php</file>
<file>unit-tests/ModelsGetterSetterTest.php</file>
<file>unit-tests/ModelsHydrationTest.php</file>
<file>unit-tests/ModelsMassAssigmentTest.php</file>
<file>unit-tests/ModelsMetadataAdaptersTest.php</file>
Expand Down

0 comments on commit 6d17755

Please sign in to comment.