/** * Returns the major framework's version * * @return string */ PHP_METHOD(Phalcon_Debug, getMajorVersion){ zval *version = NULL, *parts, *major; PHALCON_MM_GROW(); PHALCON_CALL_CE_STATIC(&version, phalcon_version_ce, "get"); PHALCON_INIT_VAR(parts); phalcon_fast_explode_str(parts, SL(" "), version); PHALCON_OBS_VAR(major); phalcon_array_fetch_long(&major, parts, 0, PH_NOISY); RETURN_CCTOR(major); }
/** * Check whether internal resource has rows to fetch * * @return boolean */ PHP_METHOD(Phalcon_Mvc_Model_Resultset_Complex, valid){ zval *type = NULL, *row = NULL, *underscore; zval *empty_str, *active_row = NULL; zval *dirty_state, *column = NULL, *alias = NULL, *source = NULL, *attributes = NULL; zval *column_map = NULL, *row_model = NULL, *attribute = NULL, *column_alias = NULL; zval *column_value = NULL; zval *value = NULL, *sql_alias = NULL, *n_alias = NULL; HashTable *ah0, *ah1; HashPosition hp0, hp1; zval **hd; int i_type, is_partial; PHALCON_MM_GROW(); type = phalcon_fetch_nproperty_this(this_ptr, SL("_type"), PH_NOISY TSRMLS_CC); i_type = (Z_TYPE_P(type) == IS_LONG) ? Z_LVAL_P(type) : phalcon_get_intval(type); is_partial = (i_type == PHALCON_MVC_MODEL_RESULTSET_TYPE_PARTIAL); type = NULL; PHALCON_INIT_VAR(row); if (is_partial) { /** * The result is bigger than 32 rows so it's retrieved one by one */ zval *result = phalcon_fetch_nproperty_this(this_ptr, SL("_result"), PH_NOISY TSRMLS_CC); if (PHALCON_IS_NOT_FALSE(result)) { PHALCON_CALL_METHOD(&row, result, "fetch", result); } else { ZVAL_FALSE(row); } } else { /** * The full rows are dumped in this_ptr->rows */ zval *rows = phalcon_fetch_nproperty_this(this_ptr, SL("_rows"), PH_NOISY TSRMLS_CC); if (Z_TYPE_P(rows) == IS_ARRAY) { phalcon_array_get_current(row, rows); if (Z_TYPE_P(row) == IS_OBJECT) { zend_hash_move_forward(Z_ARRVAL_P(rows)); } } else { ZVAL_FALSE(row); } } /** * Valid records are arrays */ if (Z_TYPE_P(row) == IS_ARRAY || Z_TYPE_P(row) == IS_OBJECT) { /** * The result type=1 so we need to build every row */ if (is_partial) { /** * Get current hydration mode */ zval *hydrate_mode = phalcon_fetch_nproperty_this(this_ptr, SL("_hydrateMode"), PH_NOISY TSRMLS_CC); zval *columns_types = phalcon_fetch_nproperty_this(this_ptr, SL("_columnTypes"), PH_NOISY TSRMLS_CC); int i_hydrate_mode = phalcon_get_intval(hydrate_mode); PHALCON_INIT_VAR(underscore); ZVAL_STRING(underscore, "_", 1); PHALCON_INIT_VAR(empty_str); ZVAL_EMPTY_STRING(empty_str); /** * Each row in a complex result is a Phalcon\Mvc\Model\Row instance */ PHALCON_INIT_VAR(active_row); switch (i_hydrate_mode) { case 0: object_init_ex(active_row, phalcon_mvc_model_row_ce); break; case 1: array_init(active_row); break; case 2: default: object_init(active_row); break; } /** * Create every record according to the column types */ /** * Set records as dirty state PERSISTENT by default */ PHALCON_INIT_VAR(dirty_state); ZVAL_LONG(dirty_state, 0); phalcon_is_iterable(columns_types, &ah0, &hp0, 0, 0); while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { PHALCON_GET_HKEY(alias, ah0, hp0); PHALCON_GET_HVALUE(column); PHALCON_OBS_NVAR(type); phalcon_array_fetch_string(&type, column, SL("type"), PH_NOISY); if (PHALCON_IS_STRING(type, "object")) { /** * Object columns are assigned column by column */ PHALCON_OBS_NVAR(source); phalcon_array_fetch_string(&source, column, SL("column"), PH_NOISY); PHALCON_OBS_NVAR(attributes); phalcon_array_fetch_string(&attributes, column, SL("attributes"), PH_NOISY); PHALCON_OBS_NVAR(column_map); phalcon_array_fetch_string(&column_map, column, SL("columnMap"), PH_NOISY); /** * Assign the values from the _source_attribute notation to its real column name */ PHALCON_INIT_NVAR(row_model); array_init(row_model); phalcon_is_iterable(attributes, &ah1, &hp1, 0, 0); while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) { PHALCON_GET_HVALUE(attribute); /** * Columns are supposed to be in the form _table_field */ PHALCON_INIT_NVAR(column_alias); PHALCON_CONCAT_VVVV(column_alias, underscore, source, underscore, attribute); PHALCON_OBS_NVAR(column_value); phalcon_array_fetch(&column_value, row, column_alias, PH_NOISY); phalcon_array_update_zval(&row_model, attribute, column_value, PH_COPY | PH_SEPARATE); zend_hash_move_forward_ex(ah1, &hp1); } /** * Generate the column value according to the hydration type */ switch (phalcon_get_intval(hydrate_mode)) { case 0: { zval *keep_snapshots, *instance; /** * Check if the resultset must keep snapshots */ if (!phalcon_array_isset_string_fetch(&keep_snapshots, column, SS("keepSnapshots"))) { keep_snapshots = PHALCON_GLOBAL(z_false); } /** * Get the base instance */ if (!phalcon_array_isset_string_fetch(&instance, column, SS("instance"))) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined index: instance"); instance = PHALCON_GLOBAL(z_null); } /** * Assign the values to the attributes using a column map */ PHALCON_CALL_CE_STATIC(&value, phalcon_mvc_model_ce, "cloneresultmap", instance, row_model, column_map, dirty_state, keep_snapshots); break; } default: /** * Other kinds of hydrations */ PHALCON_CALL_CE_STATIC(&value, phalcon_mvc_model_ce, "cloneresultmaphydrate", row_model, column_map, hydrate_mode); break; } /** * The complete object is assigned to an attribute with the name of the alias or * the model name */ PHALCON_OBS_NVAR(attribute); if (phalcon_array_isset_string(column, SS("balias"))) { phalcon_array_fetch_string(&attribute, column, SL("balias"), PH_NOISY); } } else { /** * Scalar columns are simply assigned to the result object */ if (phalcon_array_isset_string(column, SS("sqlAlias"))) { PHALCON_OBS_NVAR(sql_alias); phalcon_array_fetch_string(&sql_alias, column, SL("sqlAlias"), PH_NOISY); PHALCON_OBS_NVAR(value); phalcon_array_fetch(&value, row, sql_alias, PH_NOISY); } else { PHALCON_OBS_NVAR(value); if (phalcon_array_isset(row, alias)) { phalcon_array_fetch(&value, row, alias, PH_NOISY); } } /** * If a 'balias' is defined is not an unnamed scalar */ if (phalcon_array_isset_string(column, SS("balias"))) { PHALCON_CPY_WRT(attribute, alias); } else { PHALCON_INIT_NVAR(n_alias); phalcon_fast_str_replace(n_alias, underscore, empty_str, alias); PHALCON_CPY_WRT(attribute, n_alias); } assert(attribute != NULL); } /** * Assign the instance according to the hydration type */ if (unlikely(!attribute)) { zend_throw_exception_ex(phalcon_mvc_model_exception_ce, 0 TSRMLS_CC, "Unexpected inconsistency: attribute is NULL"); RETURN_MM(); } switch (phalcon_get_intval(hydrate_mode)) { case 1: phalcon_array_update_zval(&active_row, attribute, value, PH_COPY | PH_SEPARATE); break; default: phalcon_update_property_zval_zval(active_row, attribute, value TSRMLS_CC); break; } zend_hash_move_forward_ex(ah0, &hp0); } /** * Store the generated row in this_ptr->activeRow to be retrieved by 'current' */ phalcon_update_property_this(this_ptr, SL("_activeRow"), active_row TSRMLS_CC); } else { /** * The row is already built so we just assign it to the activeRow */ phalcon_update_property_this(this_ptr, SL("_activeRow"), row TSRMLS_CC); } RETURN_MM_TRUE; } /** * There are no results to retrieve so we update this_ptr->activeRow as false */ phalcon_update_property_bool(this_ptr, SL("_activeRow"), 0 TSRMLS_CC); RETURN_MM_FALSE; }
/** * Executes the validator * * @param Phalcon\Mvc\ModelInterface $record * @return boolean */ PHP_METHOD(Phalcon_Mvc_Model_Validator_Uniqueness, validate){ zval *record, *option = NULL, *field = NULL, *dependency_injector = NULL; zval *service, *meta_data = NULL, *bind_types, *bind_data_types = NULL; zval *column_map = NULL, *conditions, *bind_params; zval *number = NULL, *compose_field = NULL, *column_field = NULL; zval *exception_message = NULL, *value = NULL, *compose_condition = NULL; zval *bind_type = NULL, *condition = NULL, *operation_made = NULL; zval *primary_fields = NULL, *primary_field = NULL, *attribute_field = NULL; zval *join_conditions, *params; zval *message = NULL, *join_fields, *type, *is_set_code = NULL, *code = NULL; HashTable *ah0, *ah1; HashPosition hp0, hp1; zval **hd; PHALCON_MM_GROW(); phalcon_fetch_params(1, 1, 0, &record); PHALCON_INIT_VAR(option); ZVAL_STRING(option, "field", 1); PHALCON_CALL_METHOD(&field, this_ptr, "getoption", option); PHALCON_CALL_METHOD(&dependency_injector, record, "getdi"); PHALCON_INIT_VAR(service); ZVAL_STRING(service, "modelsMetadata", 1); PHALCON_CALL_METHOD(&meta_data, dependency_injector, "getshared", service); PHALCON_VERIFY_INTERFACE(meta_data, phalcon_mvc_model_metadatainterface_ce); /** * PostgreSQL check if the compared constant has the same type as the column, so we * make cast to the data passed to match those column types */ PHALCON_INIT_VAR(bind_types); array_init(bind_types); PHALCON_CALL_METHOD(&bind_data_types, meta_data, "getbindtypes", record); if (PHALCON_GLOBAL(orm).column_renaming) { PHALCON_CALL_METHOD(&column_map, meta_data, "getreversecolumnmap", record); } else { PHALCON_INIT_VAR(column_map); } PHALCON_INIT_VAR(conditions); array_init(conditions); PHALCON_INIT_VAR(bind_params); array_init(bind_params); PHALCON_INIT_VAR(number); ZVAL_LONG(number, 0); if (Z_TYPE_P(field) == IS_ARRAY) { /** * The field can be an array of values */ phalcon_is_iterable(field, &ah0, &hp0, 0, 0); while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { PHALCON_GET_HVALUE(compose_field); /** * The reversed column map is used in the case to get real column name */ if (Z_TYPE_P(column_map) == IS_ARRAY) { if (phalcon_array_isset(column_map, compose_field)) { PHALCON_OBS_NVAR(column_field); phalcon_array_fetch(&column_field, column_map, compose_field, PH_NOISY); } else { PHALCON_INIT_NVAR(exception_message); PHALCON_CONCAT_SVS(exception_message, "Column '", compose_field, "\" isn't part of the column map"); PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message); return; } } else { PHALCON_CPY_WRT(column_field, compose_field); } /** * Some database systems require that we pass the values using bind casting */ if (!phalcon_array_isset(bind_data_types, column_field)) { PHALCON_INIT_NVAR(exception_message); PHALCON_CONCAT_SVS(exception_message, "Column '", column_field, "\" isn't part of the table columns"); PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message); return; } /** * The attribute could be "protected" so we read using "readattribute" */ PHALCON_CALL_METHOD(&value, record, "readattribute", compose_field); PHALCON_INIT_NVAR(compose_condition); PHALCON_CONCAT_SVSV(compose_condition, "[", compose_field, "] = ?", number); phalcon_array_append(&conditions, compose_condition, PH_SEPARATE); phalcon_array_append(&bind_params, value, PH_SEPARATE); PHALCON_OBS_NVAR(bind_type); phalcon_array_fetch(&bind_type, bind_data_types, column_field, PH_NOISY); phalcon_array_append(&bind_types, bind_type, PH_SEPARATE); phalcon_increment(number); zend_hash_move_forward_ex(ah0, &hp0); } } else { /** * The reversed column map is used in the case to get real column name */ if (Z_TYPE_P(column_map) == IS_ARRAY) { if (phalcon_array_isset(column_map, field)) { PHALCON_OBS_NVAR(column_field); phalcon_array_fetch(&column_field, column_map, field, PH_NOISY); } else { PHALCON_INIT_NVAR(exception_message); PHALCON_CONCAT_SVS(exception_message, "Column '", field, "\" isn't part of the column map"); PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message); return; } } else { PHALCON_CPY_WRT(column_field, field); } /** * Some database systems require that we pass the values using bind casting */ if (!phalcon_array_isset(bind_data_types, column_field)) { PHALCON_INIT_NVAR(exception_message); PHALCON_CONCAT_SVS(exception_message, "Column '", column_field, "\" isn't part of the table columns"); PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message); return; } /** * We're checking the uniqueness with only one field */ PHALCON_CALL_METHOD(&value, record, "readattribute", field); PHALCON_INIT_VAR(condition); PHALCON_CONCAT_SVS(condition, "[", field, "] = ?0"); phalcon_array_append(&conditions, condition, PH_SEPARATE); phalcon_array_append(&bind_params, value, PH_SEPARATE); PHALCON_OBS_NVAR(bind_type); phalcon_array_fetch(&bind_type, bind_data_types, column_field, PH_NOISY); phalcon_array_append(&bind_types, bind_type, PH_SEPARATE); phalcon_increment(number); } /** * If the operation is update, there must be values in the object */ PHALCON_CALL_METHOD(&operation_made, record, "getoperationmade"); if (PHALCON_IS_LONG(operation_made, 2)) { /** * We build a query with the primary key attributes */ if (PHALCON_GLOBAL(orm).column_renaming) { PHALCON_CALL_METHOD(&column_map, meta_data, "getcolumnmap", record); } else { PHALCON_INIT_VAR(column_map); } PHALCON_CALL_METHOD(&primary_fields, meta_data, "getprimarykeyattributes", record); phalcon_is_iterable(primary_fields, &ah1, &hp1, 0, 0); while (zend_hash_get_current_data_ex(ah1, (void**) &hd, &hp1) == SUCCESS) { PHALCON_GET_HVALUE(primary_field); if (!phalcon_array_isset(bind_data_types, primary_field)) { PHALCON_INIT_NVAR(exception_message); PHALCON_CONCAT_SVS(exception_message, "Column '", primary_field, "\" isn't part of the table columns"); PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message); return; } /** * Rename the column if there is a column map */ if (Z_TYPE_P(column_map) == IS_ARRAY) { if (phalcon_array_isset(column_map, primary_field)) { PHALCON_OBS_NVAR(attribute_field); phalcon_array_fetch(&attribute_field, column_map, primary_field, PH_NOISY); } else { PHALCON_INIT_NVAR(exception_message); PHALCON_CONCAT_SVS(exception_message, "Column '", primary_field, "\" isn't part of the column map"); PHALCON_THROW_EXCEPTION_ZVAL(phalcon_mvc_model_exception_ce, exception_message); return; } } else { PHALCON_CPY_WRT(attribute_field, primary_field); } /** * Create a condition based on the renamed primary key */ PHALCON_CALL_METHOD(&value, record, "readattribute", primary_field); PHALCON_INIT_NVAR(condition); PHALCON_CONCAT_SVSV(condition, "[", attribute_field, "] <> ?", number); phalcon_array_append(&conditions, condition, PH_SEPARATE); phalcon_array_append(&bind_params, value, PH_SEPARATE); PHALCON_OBS_NVAR(bind_type); phalcon_array_fetch(&bind_type, bind_data_types, primary_field, PH_NOISY); phalcon_array_append(&bind_types, bind_type, PH_SEPARATE); phalcon_increment(number); zend_hash_move_forward_ex(ah1, &hp1); } } PHALCON_INIT_VAR(join_conditions); phalcon_fast_join_str(join_conditions, SL(" AND "), conditions TSRMLS_CC); /** * We don't trust the user, so we pass the parameters as bound parameters */ PHALCON_INIT_VAR(params); array_init_size(params, 4); phalcon_array_update_string(¶ms, SL("di"), dependency_injector, PH_COPY); phalcon_array_update_string(¶ms, SL("conditions"), join_conditions, PH_COPY); phalcon_array_update_string(¶ms, SL("bind"), bind_params, PH_COPY); phalcon_array_update_string(¶ms, SL("bindTypes"), bind_types, PH_COPY); /** * Check using a standard count */ PHALCON_CALL_CE_STATIC(&number, Z_OBJCE_P(record), "count", params); if (!PHALCON_IS_LONG(number, 0)) { /** * Check if the developer has defined a custom message */ PHALCON_INIT_NVAR(option); PHALCON_ZVAL_MAYBE_INTERNED_STRING(option, phalcon_interned_message); PHALCON_CALL_METHOD(&message, this_ptr, "getoption", option); if (!zend_is_true(message)) { if (Z_TYPE_P(field) == IS_ARRAY) { PHALCON_INIT_VAR(join_fields); phalcon_fast_join_str(join_fields, SL(", "), field TSRMLS_CC); PHALCON_INIT_NVAR(message); PHALCON_CONCAT_SVS(message, "Value of fields: '", join_fields, "' are already present in another record"); } else { PHALCON_INIT_NVAR(message); PHALCON_CONCAT_SVS(message, "Value of field: '", field, "' is already present in another record"); } } /** * Append the message to the validator */ PHALCON_INIT_VAR(type); ZVAL_STRING(type, "Unique", 1); /* * Is code set */ PHALCON_INIT_NVAR(option); PHALCON_ZVAL_MAYBE_INTERNED_STRING(option, phalcon_interned_code); PHALCON_CALL_METHOD(&is_set_code, this_ptr, "issetoption", option); if (zend_is_true(is_set_code)) { PHALCON_CALL_METHOD(&code, this_ptr, "getoption", option); } else { PHALCON_INIT_VAR(code); ZVAL_LONG(code, 0); } PHALCON_CALL_METHOD(NULL, this_ptr, "appendmessage", message, field, type, code); RETURN_MM_FALSE; } RETURN_MM_TRUE; }
/** * Magic method __get * * @param string $propertyName */ PHP_METHOD(Phalcon_DI_Injectable, __get){ zval **property_name, *dependency_injector = NULL; zval *has_service = NULL, *service = NULL, *class_name, *arguments, *result = NULL; phalcon_fetch_params_ex(1, 0, &property_name); PHALCON_ENSURE_IS_STRING(property_name); PHALCON_MM_GROW(); dependency_injector = phalcon_fetch_nproperty_this(this_ptr, SL("_dependencyInjector"), PH_NOISY TSRMLS_CC); if (Z_TYPE_P(dependency_injector) != IS_OBJECT) { dependency_injector = NULL; PHALCON_CALL_CE_STATIC(&dependency_injector, phalcon_di_ce, "getdefault"); if (Z_TYPE_P(dependency_injector) != IS_OBJECT) { PHALCON_THROW_EXCEPTION_STR(phalcon_di_exception_ce, "A dependency injection object is required to access the application services"); return; } } PHALCON_CALL_METHOD(&has_service, dependency_injector, "has", *property_name); if (zend_is_true(has_service)) { PHALCON_CALL_METHOD(&result, dependency_injector, "getshared", *property_name); phalcon_update_property_zval(this_ptr, Z_STRVAL_PP(property_name), Z_STRLEN_PP(property_name), result TSRMLS_CC); RETURN_CTOR(result); } assert(Z_TYPE_PP(property_name) == IS_STRING); if (Z_STRLEN_PP(property_name) == sizeof("di")-1 && !memcmp(Z_STRVAL_PP(property_name), "di", sizeof("di")-1)) { zend_update_property(phalcon_di_injectable_ce, getThis(), SL("di"), dependency_injector TSRMLS_CC); RETURN_CTOR(dependency_injector); } /** * Accessing the persistent property will create a session bag in any class */ if (Z_STRLEN_PP(property_name) == sizeof("persistent")-1 && !memcmp(Z_STRVAL_PP(property_name), "persistent", sizeof("persistent")-1)) { const char *cn = Z_OBJCE_P(getThis())->name; MAKE_STD_ZVAL(class_name); PHALCON_ZVAL_MAYBE_INTERNED_STRING(class_name, cn); PHALCON_INIT_VAR(arguments); array_init_size(arguments, 1); add_next_index_zval(arguments, class_name); PHALCON_INIT_NVAR(service); ZVAL_STRING(service, "sessionBag", 1); PHALCON_CALL_METHOD(&result, dependency_injector, "get", service, arguments); zend_update_property(phalcon_di_injectable_ce, getThis(), SL("persistent"), result TSRMLS_CC); RETURN_CTOR(result); } /** * A notice is shown if the property is not defined or is not a valid service */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Access to undefined property %s::%s", Z_OBJCE_P(getThis())->name, Z_STRVAL_PP(property_name)); RETURN_MM_NULL(); }