From f62b248af9f8c3398c9380b9879f120d57964cb4 Mon Sep 17 00:00:00 2001 From: Serghei Iakovlev Date: Tue, 5 May 2020 22:37:31 +0300 Subject: [PATCH 1/2] Changed MetaData::getDI to throw exception See: https://github.com/phalcon/cphalcon/issues/15011 --- CHANGELOG-4.0.md | 1 + ext/phalcon/mvc/model.zep.c | 2 +- ext/phalcon/mvc/model/manager.zep.c | 2 +- ext/phalcon/mvc/model/metadata.zep.c | 82 ++++++++++++------- phalcon/Mvc/Model/MetaData.zep | 16 +++- .../Mvc/Model/MetaData/GetSetDICest.php | 51 ++++++++++-- 6 files changed, 113 insertions(+), 41 deletions(-) diff --git a/CHANGELOG-4.0.md b/CHANGELOG-4.0.md index 5bfd33fa897..b06935467b8 100644 --- a/CHANGELOG-4.0.md +++ b/CHANGELOG-4.0.md @@ -10,6 +10,7 @@ - Changed return type hint for `Phalcon\Mvc\ModelInterface::sum` [#15000](https://github.com/phalcon/cphalcon/issues/15000) - Changed return type for `Phalcon\Mvc\Model\Criteria::getLimit` so that integer, NULL or array will be returned [#15004](https://github.com/phalcon/cphalcon/issues/15004) - Changed return type hint for `Phalcon\Mvc\Model\Manager::getCustomEventsManager` to return NULL instead of boolean FALSE if there is no special events manager [#15008](https://github.com/phalcon/cphalcon/issues/15008) +- Changed `Phalcon\Mvc\Model\MetaData::getDI` so that now it will throw a `Phalcon\Mvc\Model\Exception` if there is no `DiInterface` instance [#15011](https://github.com/phalcon/cphalcon/issues/15011) ## Fixed - Fixed `Phalcon\Mvc\Model\Query\Builder::getPhql` to add single quote between string value on a simple condition [#14874](https://github.com/phalcon/cphalcon/issues/14874) diff --git a/ext/phalcon/mvc/model.zep.c b/ext/phalcon/mvc/model.zep.c index ffa03afdc31..8f4d84ee5a7 100644 --- a/ext/phalcon/mvc/model.zep.c +++ b/ext/phalcon/mvc/model.zep.c @@ -2716,7 +2716,7 @@ PHP_METHOD(Phalcon_Mvc_Model, getDirtyState) { } /** - * Returns the custom events manager + * Returns the custom events manager or null if there is no custom events manager */ PHP_METHOD(Phalcon_Mvc_Model, getEventsManager) { diff --git a/ext/phalcon/mvc/model/manager.zep.c b/ext/phalcon/mvc/model/manager.zep.c index 4244a873d60..7ab3080c393 100644 --- a/ext/phalcon/mvc/model/manager.zep.c +++ b/ext/phalcon/mvc/model/manager.zep.c @@ -258,7 +258,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Manager, setCustomEventsManager) { } /** - * Returns a custom events manager related to a model a null otherwise + * Returns a custom events manager related to a model or null if there is no related events manager */ PHP_METHOD(Phalcon_Mvc_Model_Manager, getCustomEventsManager) { diff --git a/ext/phalcon/mvc/model/metadata.zep.c b/ext/phalcon/mvc/model/metadata.zep.c index 2fa70e4ca85..ef2441ee17e 100644 --- a/ext/phalcon/mvc/model/metadata.zep.c +++ b/ext/phalcon/mvc/model/metadata.zep.c @@ -421,10 +421,36 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, getDataTypesNumeric) { */ PHP_METHOD(Phalcon_Mvc_Model_MetaData, getDI) { + zval container, _0, _1$$3, _2$$3, _4$$3; + zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL; + zend_long ZEPHIR_LAST_CALL_STATUS; + zephir_fcall_cache_entry *_3 = NULL; zval *this_ptr = getThis(); + ZVAL_UNDEF(&container); + ZVAL_UNDEF(&_0); + ZVAL_UNDEF(&_1$$3); + ZVAL_UNDEF(&_2$$3); + ZVAL_UNDEF(&_4$$3); - RETURN_MEMBER(getThis(), "container"); + ZEPHIR_MM_GROW(); + + zephir_read_property(&_0, this_ptr, SL("container"), PH_NOISY_CC | PH_READONLY); + ZEPHIR_CPY_WRT(&container, &_0); + if (Z_TYPE_P(&container) != IS_OBJECT) { + ZEPHIR_INIT_VAR(&_1$$3); + object_init_ex(&_1$$3, phalcon_mvc_model_exception_ce); + ZEPHIR_INIT_VAR(&_4$$3); + ZVAL_STRING(&_4$$3, "internal services"); + ZEPHIR_CALL_CE_STATIC(&_2$$3, phalcon_mvc_model_exception_ce, "containerservicenotfound", &_3, 0, &_4$$3); + zephir_check_call_status(); + ZEPHIR_CALL_METHOD(NULL, &_1$$3, "__construct", NULL, 6, &_2$$3); + zephir_check_call_status(); + zephir_throw_exception_debug(&_1$$3, "phalcon/Mvc/Model/MetaData.zep", 288); + ZEPHIR_MM_RESTORE(); + return; + } + RETURN_CCTOR(&container); } @@ -459,7 +485,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, getEmptyStringAttributes) { ZEPHIR_CALL_METHOD(&data, this_ptr, "readmetadataindex", NULL, 25, model, &_0); zephir_check_call_status(); if (UNEXPECTED(Z_TYPE_P(&data) != IS_ARRAY)) { - ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 305); + ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 315); return; } RETURN_CCTOR(&data); @@ -530,7 +556,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, getNonPrimaryKeyAttributes) { ZEPHIR_CALL_METHOD(&data, this_ptr, "readmetadataindex", NULL, 25, model, &_0); zephir_check_call_status(); if (UNEXPECTED(Z_TYPE_P(&data) != IS_ARRAY)) { - ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 345); + ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 355); return; } RETURN_CCTOR(&data); @@ -568,7 +594,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, getNotNullAttributes) { ZEPHIR_CALL_METHOD(&data, this_ptr, "readmetadataindex", NULL, 25, model, &_0); zephir_check_call_status(); if (UNEXPECTED(Z_TYPE_P(&data) != IS_ARRAY)) { - ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 369); + ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 379); return; } RETURN_CCTOR(&data); @@ -606,7 +632,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, getPrimaryKeyAttributes) { ZEPHIR_CALL_METHOD(&data, this_ptr, "readmetadataindex", NULL, 25, model, &_0); zephir_check_call_status(); if (UNEXPECTED(Z_TYPE_P(&data) != IS_ARRAY)) { - ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 393); + ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 403); return; } RETURN_CCTOR(&data); @@ -649,7 +675,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, getReverseColumnMap) { _1 = Z_TYPE_P(&data) != IS_ARRAY; } if (UNEXPECTED(_1)) { - ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 420); + ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "The meta-data is invalid or is corrupt", "phalcon/Mvc/Model/MetaData.zep", 430); return; } RETURN_CCTOR(&data); @@ -724,7 +750,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, hasAttribute) { } ZEPHIR_CALL_METHOD(&_0, this_ptr, "readmetadata", NULL, 27, model); zephir_check_call_status(); - zephir_array_fetch_long(&_1, &_0, 4, PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 460); + zephir_array_fetch_long(&_1, &_0, 4, PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 470); RETURN_MM_BOOL(zephir_array_isset(&_1, &attribute)); } @@ -833,7 +859,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, readColumnMap) { zephir_check_call_status(); zephir_read_property(&_1$$4, this_ptr, SL("columnMap"), PH_NOISY_CC | PH_READONLY); ZEPHIR_OBS_NVAR(&data); - zephir_array_fetch(&data, &_1$$4, &keyName, PH_NOISY, "phalcon/Mvc/Model/MetaData.zep", 509); + zephir_array_fetch(&data, &_1$$4, &keyName, PH_NOISY, "phalcon/Mvc/Model/MetaData.zep", 519); } RETURN_CCTOR(&data); @@ -888,7 +914,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, readColumnMapIndex) { zephir_check_call_status(); zephir_read_property(&_1$$4, this_ptr, SL("columnMap"), PH_NOISY_CC | PH_READONLY); ZEPHIR_OBS_NVAR(&columnMapModel); - zephir_array_fetch(&columnMapModel, &_1$$4, &keyName, PH_NOISY, "phalcon/Mvc/Model/MetaData.zep", 540); + zephir_array_fetch(&columnMapModel, &_1$$4, &keyName, PH_NOISY, "phalcon/Mvc/Model/MetaData.zep", 550); } zephir_array_isset_long_fetch(&map, &columnMapModel, index, 1); RETURN_CTOR(&map); @@ -944,7 +970,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, readMetaData) { zephir_check_call_status(); } zephir_read_property(&_3, this_ptr, SL("metaData"), PH_NOISY_CC | PH_READONLY); - zephir_array_fetch(&_4, &_3, &key, PH_NOISY | PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 576); + zephir_array_fetch(&_4, &_3, &key, PH_NOISY | PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 586); RETURN_CTOR(&_4); } @@ -997,14 +1023,14 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, readMetaDataIndex) { ZEPHIR_CONCAT_VSVV(&_1, &_0, "-", &schema, &source); zephir_get_strval(&key, &_1); zephir_read_property(&_2, this_ptr, SL("metaData"), PH_NOISY_CC | PH_READONLY); - zephir_array_fetch(&_3, &_2, &key, PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 604); + zephir_array_fetch(&_3, &_2, &key, PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 614); if (!(zephir_array_isset_long(&_3, index))) { ZEPHIR_CALL_METHOD(NULL, this_ptr, "initialize", NULL, 28, model, &key, &source, &schema); zephir_check_call_status(); } zephir_read_property(&_4, this_ptr, SL("metaData"), PH_NOISY_CC | PH_READONLY); - zephir_array_fetch(&_5, &_4, &key, PH_NOISY | PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 608); - zephir_array_fetch_long(&_6, &_5, index, PH_NOISY | PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 608); + zephir_array_fetch(&_5, &_4, &key, PH_NOISY | PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 618); + zephir_array_fetch_long(&_6, &_5, index, PH_NOISY | PH_READONLY, "phalcon/Mvc/Model/MetaData.zep", 618); RETURN_CTOR(&_6); } @@ -1299,7 +1325,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, writeMetaDataIndex) { _1 = ((Z_TYPE_P(data) == IS_TRUE || Z_TYPE_P(data) == IS_FALSE) != 1); } if (UNEXPECTED(_1)) { - ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "Invalid data for index", "phalcon/Mvc/Model/MetaData.zep", 743); + ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_mvc_model_exception_ce, "Invalid data for index", "phalcon/Mvc/Model/MetaData.zep", 753); return; } ZEPHIR_CALL_METHOD(&source, model, "getsource", NULL, 0); @@ -1329,7 +1355,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, initialize) { zval prefixKey; zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL; zend_long ZEPHIR_LAST_CALL_STATUS; - zval *model, model_sub, *key, key_sub, *table, table_sub, *schema, schema_sub, strategy, className, metaData, data, modelMetadata, modelColumnMap, container, keyName, _5, _6, _0$$3, _1$$4, _2$$8, _3$$8, _4$$9, _7$$13; + zval *model, model_sub, *key, key_sub, *table, table_sub, *schema, schema_sub, strategy, className, metaData, data, modelMetadata, modelColumnMap, container, keyName, _4, _5, _0$$3, _1$$4, _2$$8, _3$$8; zval *this_ptr = getThis(); ZVAL_UNDEF(&model_sub); @@ -1344,14 +1370,12 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, initialize) { ZVAL_UNDEF(&modelColumnMap); ZVAL_UNDEF(&container); ZVAL_UNDEF(&keyName); + ZVAL_UNDEF(&_4); ZVAL_UNDEF(&_5); - ZVAL_UNDEF(&_6); ZVAL_UNDEF(&_0$$3); ZVAL_UNDEF(&_1$$4); ZVAL_UNDEF(&_2$$8); ZVAL_UNDEF(&_3$$8); - ZVAL_UNDEF(&_4$$9); - ZVAL_UNDEF(&_7$$13); ZVAL_UNDEF(&prefixKey); ZEPHIR_MM_GROW(); @@ -1385,13 +1409,13 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, initialize) { ZEPHIR_CONCAT_SV(&_3$$8, "Invalid meta-data for model ", &className); ZEPHIR_CALL_METHOD(NULL, &_2$$8, "__construct", NULL, 6, &_3$$8); zephir_check_call_status(); - zephir_throw_exception_debug(&_2$$8, "phalcon/Mvc/Model/MetaData.zep", 795); + zephir_throw_exception_debug(&_2$$8, "phalcon/Mvc/Model/MetaData.zep", 805); ZEPHIR_MM_RESTORE(); return; } } else { - zephir_read_property(&_4$$9, this_ptr, SL("container"), PH_NOISY_CC | PH_READONLY); - ZEPHIR_CPY_WRT(&container, &_4$$9); + ZEPHIR_CALL_METHOD(&container, this_ptr, "getdi", NULL, 0); + zephir_check_call_status(); ZEPHIR_CALL_METHOD(&strategy, this_ptr, "getstrategy", NULL, 0); zephir_check_call_status(); ZEPHIR_CALL_METHOD(&modelMetadata, &strategy, "getmetadata", NULL, 0, model, &container); @@ -1408,13 +1432,13 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, initialize) { } ZEPHIR_INIT_VAR(&keyName); zephir_fast_strtolower(&keyName, &className); - zephir_read_property(&_5, this_ptr, SL("columnMap"), PH_NOISY_CC | PH_READONLY); - if (zephir_array_isset(&_5, &keyName)) { + zephir_read_property(&_4, this_ptr, SL("columnMap"), PH_NOISY_CC | PH_READONLY); + if (zephir_array_isset(&_4, &keyName)) { RETURN_MM_NULL(); } - ZEPHIR_INIT_VAR(&_6); - ZEPHIR_CONCAT_SV(&_6, "map-", &keyName); - zephir_get_strval(&prefixKey, &_6); + ZEPHIR_INIT_VAR(&_5); + ZEPHIR_CONCAT_SV(&_5, "map-", &keyName); + zephir_get_strval(&prefixKey, &_5); ZEPHIR_CALL_METHOD(&data, this_ptr, "read", NULL, 0, &prefixKey); zephir_check_call_status(); if (Z_TYPE_P(&data) != IS_NULL) { @@ -1422,8 +1446,8 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, initialize) { RETURN_MM_NULL(); } if (Z_TYPE_P(&strategy) != IS_OBJECT) { - zephir_read_property(&_7$$13, this_ptr, SL("container"), PH_NOISY_CC | PH_READONLY); - ZEPHIR_CPY_WRT(&container, &_7$$13); + ZEPHIR_CALL_METHOD(&container, this_ptr, "getdi", NULL, 0); + zephir_check_call_status(); ZEPHIR_CALL_METHOD(&strategy, this_ptr, "getstrategy", NULL, 0); zephir_check_call_status(); } @@ -1463,7 +1487,7 @@ PHP_METHOD(Phalcon_Mvc_Model_MetaData, throwWriteException) { object_init_ex(&_0$$3, phalcon_mvc_model_exception_ce); ZEPHIR_CALL_METHOD(NULL, &_0$$3, "__construct", NULL, 6, &message); zephir_check_call_status(); - zephir_throw_exception_debug(&_0$$3, "phalcon/Mvc/Model/MetaData.zep", 879); + zephir_throw_exception_debug(&_0$$3, "phalcon/Mvc/Model/MetaData.zep", 889); ZEPHIR_MM_RESTORE(); return; } else { diff --git a/phalcon/Mvc/Model/MetaData.zep b/phalcon/Mvc/Model/MetaData.zep index 030d646c432..79ce9b33090 100644 --- a/phalcon/Mvc/Model/MetaData.zep +++ b/phalcon/Mvc/Model/MetaData.zep @@ -278,7 +278,17 @@ abstract class MetaData implements InjectionAwareInterface, MetaDataInterface */ public function getDI() -> { - return this->container; + var container; + + let container = this->container; + + if typeof container != "object" { + throw new Exception( + Exception::containerServiceNotFound("internal services") + ); + } + + return container; } /** @@ -798,7 +808,7 @@ abstract class MetaData implements InjectionAwareInterface, MetaDataInterface /** * Get the meta-data extraction strategy */ - let container = this->container, + let container = this->getDI(), strategy = this->getStrategy(), modelMetadata = strategy->getMetaData( model, @@ -849,7 +859,7 @@ abstract class MetaData implements InjectionAwareInterface, MetaDataInterface * Get the meta-data extraction strategy */ if typeof strategy != "object" { - let container = this->container, + let container = this->getDI(), strategy = this->getStrategy(); } diff --git a/tests/database/Mvc/Model/MetaData/GetSetDICest.php b/tests/database/Mvc/Model/MetaData/GetSetDICest.php index 4d5862202f0..7343a950abd 100644 --- a/tests/database/Mvc/Model/MetaData/GetSetDICest.php +++ b/tests/database/Mvc/Model/MetaData/GetSetDICest.php @@ -5,8 +5,8 @@ * * (c) Phalcon Team * - * For the full copyright and license information, please view the LICENSE.txt - * file that was distributed with this source code. + * For the full copyright and license information, please view the + * LICENSE.txt file that was distributed with this source code. */ declare(strict_types=1); @@ -14,21 +14,35 @@ namespace Phalcon\Test\Database\Mvc\Model\MetaData; use DatabaseTester; +use Phalcon\Mvc\Model\Exception as ExpectedException; use Phalcon\Mvc\Model\MetaData\Memory; +use Phalcon\Storage\Exception; use Phalcon\Test\Fixtures\Traits\DiTrait; class GetSetDICest { use DiTrait; - public function _before(DatabaseTester $I) + /** + * Executed before each test + * + * @param DatabaseTester $I + * @return void + */ + public function _before(DatabaseTester $I): void { - $this->setNewFactoryDefault(); + try { + $this->setNewFactoryDefault(); + } catch (Exception $e) { + $I->fail($e->getMessage()); + } } /** * Tests Phalcon\Mvc\Model\MetaData :: getDI() / setDI() * + * @param DatabaseTester $I + * * @author Phalcon Team * @since 2020-02-01 * @@ -39,11 +53,34 @@ public function mvcModelMetadataGetSetDI(DatabaseTester $I) $I->wantToTest('Mvc\Model\MetaData - getDI() / setDI()'); $metadata = new Memory(); - - $I->assertNull($metadata->getDI()); - $metadata->setDI($this->container); $I->assertEquals($this->container, $metadata->getDI()); } + + /** + * Tests Phalcon\Mvc\Model\MetaData :: getDI() - exception + * + * @param DatabaseTester $I + * + * @author Phalcon Team + * @since 2020-05-05 + * + * @group common + */ + public function mvcModelMetadataGetDIThrowsException(DatabaseTester $I) + { + $I->wantToTest('Mvc\Model\MetaData - getDI() - exception'); + + $I->expectThrowable( + new ExpectedException( + 'A dependency injection container is required to access internal services' + ), + function () { + (new Memory())->getDI(); + } + ); + } + + } From 13dba63886f881257f301eb1c887d5947aa99ee9 Mon Sep 17 00:00:00 2001 From: Serghei Iakovlev Date: Tue, 5 May 2020 22:53:03 +0300 Subject: [PATCH 2/2] Correct code style --- tests/database/Mvc/Model/MetaData/GetSetDICest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/database/Mvc/Model/MetaData/GetSetDICest.php b/tests/database/Mvc/Model/MetaData/GetSetDICest.php index 7343a950abd..ad51469cd2f 100644 --- a/tests/database/Mvc/Model/MetaData/GetSetDICest.php +++ b/tests/database/Mvc/Model/MetaData/GetSetDICest.php @@ -81,6 +81,4 @@ function () { } ); } - - }