diff --git a/CHANGELOG-5.0.md b/CHANGELOG-5.0.md index cf6acda1c4..965b76895f 100644 --- a/CHANGELOG-5.0.md +++ b/CHANGELOG-5.0.md @@ -4,6 +4,8 @@ ### Changed +- Changed `Phalcon\Mvc\Model::toArray` to use getters if present [#16320](https://github.com/phalcon/cphalcon/issues/16320) + ### Added ### Fixed diff --git a/phalcon/Mvc/Model.zep b/phalcon/Mvc/Model.zep index 3fc3a8c6ab..b16403129a 100644 --- a/phalcon/Mvc/Model.zep +++ b/phalcon/Mvc/Model.zep @@ -3277,7 +3277,7 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface, */ public function toArray(columns = null) -> array { - var metaData, columnMap, attribute, attributeField, value; + var attribute, attributeField, columnMap, metaData, method, value; array data; let data = [], @@ -3316,7 +3316,14 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface, } } - if fetch value, this->{attributeField} { + /** + * Check if there is a getter for this property + */ + let method = "get" . camelize(attributeField); + + if method_exists(this, method) { + let data[attributeField] = this->{method}(); + } elseif fetch value, this->{attributeField} { let data[attributeField] = value; } else { let data[attributeField] = null; diff --git a/tests/_data/fixtures/models/InvoicesGetters.php b/tests/_data/fixtures/models/InvoicesGetters.php new file mode 100644 index 0000000000..7afed10bba --- /dev/null +++ b/tests/_data/fixtures/models/InvoicesGetters.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Phalcon\Tests\Fixtures\models; + +use Phalcon\Tests\Models\Invoices; + +/** + * Class InvoicesGetters + */ +class InvoicesGetters extends Invoices +{ + /** + * @return bool|null + */ + public function getInvTitle(): string + { + return $this->inv_title . '!' . $this->inv_id; + } +} diff --git a/tests/database/Mvc/Model/ToArrayCest.php b/tests/database/Mvc/Model/ToArrayCest.php index 3b9cdb5bff..ab65eac398 100644 --- a/tests/database/Mvc/Model/ToArrayCest.php +++ b/tests/database/Mvc/Model/ToArrayCest.php @@ -17,10 +17,16 @@ use PDO; use Phalcon\Mvc\Model\Manager; use Phalcon\Tests\Fixtures\Migrations\InvoicesMigration; +use Phalcon\Tests\Fixtures\Migrations\SettersMigration; +use Phalcon\Tests\Fixtures\Migrations\SourcesMigration; +use Phalcon\Tests\Fixtures\models\InvoicesGetters; +use Phalcon\Tests\Fixtures\models\SourcesGetters; use Phalcon\Tests\Fixtures\Traits\DiTrait; use Phalcon\Tests\Models\Invoices; use Phalcon\Tests\Models\InvoicesMap; +use Phalcon\Tests\Models\Sources; +use function date; use function uniqid; class ToArrayCest @@ -322,4 +328,52 @@ public function mvcModelToArrayExecuteColumnNotInColumnMap(DatabaseTester $I) $actual = $result->toArray(); $I->assertSame($expected, $actual); } + + /** + * Tests Phalcon\Mvc\Model\ :: save() with property source + * + * @author Phalcon Team + * @since 2019-11-16 + * @issue #11922 + * + * @group mysql + * @group sqlite + */ + public function mvcModelToArrayModelWithGetters(DatabaseTester $I) + { + $I->wantToTest('Mvc\Model - toArray - model with getters'); + + /** @var PDO $connection */ + $connection = $I->getConnection(); + $title = uniqid('inv-'); + $date = date('Y-m-d H:i:s'); + + $migration = new InvoicesMigration($connection); + $migration->insert(4, 1, 0, $title, 111.26, $date); + + $model = InvoicesGetters::findFirst(4); + + $class = InvoicesGetters::class; + $I->assertInstanceOf($class, $model); + + $expected = 4; + $actual = $model->inv_id; + $I->assertEquals($expected, $actual); + + $expected = [ + 'inv_id' => '4', + 'inv_cst_id' => '1', + 'inv_status_flag' => '0', + 'inv_title' => $title . '!4', + 'inv_total' => '111.26', + 'inv_created_at' => $date, + ]; + + $actual = $model->toArray(); + /** + * assertEquals here because sqlite returns strings in different + * PHP versions + */ + $I->assertEquals($expected, $actual); + } }