summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcarl <>2007-08-05 14:37:09 +0000
committercarl <>2007-08-05 14:37:09 +0000
commit90de6081224723aaea97522290a80e764a6b0900 (patch)
tree92e2f1a1daa60aa839a5aa1afb6d81008b4c5c23
parentca5a6c8a86005dc13fa14d12282c375baf91a738 (diff)
#677 - Improved error reporting for the TInvalidDataValueException
-rw-r--r--framework/Exceptions/messages.txt844
-rw-r--r--framework/TComponent.php1682
2 files changed, 1263 insertions, 1263 deletions
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt
index 24bb417a..372b8501 100644
--- a/framework/Exceptions/messages.txt
+++ b/framework/Exceptions/messages.txt
@@ -1,423 +1,423 @@
-prado_application_singleton_required = Prado.Application must only be set once.
-prado_component_unknown = Unknown component type '{0}'. This may be caused by following parsing error in the {0} class file: {1}
-prado_using_invalid = '{0}' is not a valid namespace to be used. Make sure '.*' is appended if you want to use a namespace referring to a directory.
-prado_alias_redefined = Alias '{0}' cannot be redefined.
-prado_alias_invalid = Alias '{0}' refers to an invalid path '{1}'. Only existing directories can be aliased.
-prado_aliasname_invalid = Alias '{0}' contains invalid character '.'.
-
-component_property_undefined = Component property '{0}.{1}' is not defined.
-component_property_readonly = Component property '{0}.{1}' is read-only.
-component_event_undefined = Component event '{0}.{1}' is not defined.
-component_eventhandler_invalid = Component event '{0}.{1}' is attached with an invalid event handler.
-component_expression_invalid = Component '{0}' is evaluating an invalid expression '{1}' : {2}.
-component_statements_invalid = Component '{0}' is evaluating invalid PHP statements '{1}' : {2}.
-
-propertyvalue_enumvalue_invalid = Value '{0}' is a not valid enumeration value ({1}).
-
-list_index_invalid = Index '{0}' is out of range.
-list_item_inexistent = The item cannot be found in the list.
-list_data_not_iterable = Data must be either an array or an object implementing Traversable interface.
-list_readonly = {0} is read-only.
-
-map_addition_disallowed = The new item cannot be added to the map.
-map_item_unremovable = The item cannot be removed from the map.
-map_data_not_iterable = Data must be either an array or an object implementing Traversable interface.
-map_readonly = {0} is read-only.
-
-application_includefile_invalid = Unable to find application configuration {0}. Make sure it is in namespace format and the file ends with ".xml".
-application_basepath_invalid = Application base path '{0}' does not exist or is not a directory.
-application_runtimepath_invalid = Application runtime path '{0}' does not exist or is not writable by Web server process.
-application_service_invalid = Service '{0}' must implement IService interface.
-application_service_unknown = Requested service '{0}' is not defined.
-application_unavailable = Application is unavailable at this time.
-application_service_unavailable = Service '{0}' is unavailable at this time.
-application_moduleid_duplicated = Application module ID '{0}' is not unique.
-application_runtimepath_failed = Unable to create runtime path '{0}'. Make sure the parent directory exists and is writable by the Web process.
-
-appconfig_aliaspath_invalid = Application configuration <alias id="{0}"> uses an invalid file path "{1}".
-appconfig_alias_invalid = Application configuration <alias> element must have an "id" attribute and a "path" attribute.
-appconfig_alias_redefined = Application configuration <alias id="{0}"> cannot be redefined.
-appconfig_using_invalid = Application configuration <using> element must have a "namespace" attribute.
-appconfig_moduleid_required = Application configuration <module> element must have an "id" attribute.
-appconfig_moduletype_required = Application configuration <module id="{0}"> must have a "class" attribute.
-appconfig_serviceid_required = Application configuration <service> element must have an "id" attribute.
-appconfig_servicetype_required = Application configuration <service id="{0}"> must have a "class" attribute.
-appconfig_parameterid_required = Application configuration <parameter> element must have an "id" attribute.
-appconfig_includefile_required = Application configuration <include> element must have a "file" attribute.
-
-securitymanager_validationkey_invalid = TSecurityManager.ValidationKey must not be empty.
-securitymanager_encryptionkey_invalid = TSecurityManager.EncryptionKey must not be empty.
-securitymanager_mcryptextension_required = Mcrypt PHP extension is required in order to use TSecurityManager's encryption feature.
-
-uri_format_invalid = '{0}' is not a valid URI.
-
-httprequest_separator_invalid = THttpRequest.UrlParamSeparator can only contain a single character.
-httprequest_urlmanager_inexist = THttpRequest.UrlManager '{0}' does not point to an existing module.
-httprequest_urlmanager_invalid = THttpRequest.UrlManager '{0}' must point to a module extending from TUrlManager.
-
-httpcookiecollection_httpcookie_required = THttpCookieCollection can only accept THttpCookie objects.
-
-httpresponse_bufferoutput_unchangeable = THttpResponse.BufferOutput cannot be modified after THttpResponse is initialized.
-httpresponse_file_inexistent = THttpResponse cannot send file '{0}'. The file does not exist.
-
-httpsession_sessionid_unchangeable = THttpSession.SessionID cannot be modified after the session is started.
-httpsession_sessionname_unchangeable = THttpSession.SessionName cannot be modified after the session is started.
-httpsession_sessionname_invalid = THttpSession.SessionName must contain alphanumeric characters only.
-httpsession_savepath_unchangeable = THttpSession.SavePath cannot be modified after the session is started.
-httpsession_savepath_invalid = THttpSession.SavePath '{0}' is invalid.
-httpsession_storage_unchangeable = THttpSession.Storage cannot be modified after the session is started.
-httpsession_cookiemode_unchangeable = THttpSession.CookieMode cannot be modified after the session is started.
-httpsession_autostart_unchangeable = THttpSession.AutoStart cannot be modified after the session module is initialized.
-httpsession_gcprobability_unchangeable = THttpSession.GCProbability cannot be modified after the session is started.
-httpsession_gcprobability_invalid = THttpSession.GCProbability must be an integer between 0 and 100.
-httpsession_transid_unchangeable = THttpSession.UseTransparentSessionID cannot be modified after the session is started.
-httpsession_maxlifetime_unchangeable = THttpSession.Timeout cannot be modified after the session is started.
-
-assetmanager_basepath_invalid = TAssetManager.BasePath '{0}' is invalid. Make sure it is in namespace form and points to a directory writable by the Web server process.
-assetmanager_basepath_unchangeable = TAssetManager.BasePath cannot be modified after the module is initialized.
-assetmanager_baseurl_unchangeable = TAssetManager.BaseUrl cannot be modified after the module is initialized.
-assetmanager_filepath_invalid = TAssetManager is publishing an invalid file '{0}'.
-assetmanager_tarchecksum_invalid = TAssetManager is publishing a tar file with invalid checksum '{0}'.
-assetmanager_tarfile_invalid = TAssetManager is publishing an invalid tar file '{0}'.
-assetmanager_source_directory_invalid = TAssetManager is copying an invalid directory '{0}'.
-
-cache_primary_duplicated = At most one primary cache module is allowed. {0} is trying to register as another primary cache.
-sqlitecache_extension_required = TSqliteCache requires SQLite PHP extension.
-sqlitecache_dbfile_required = TSqliteCache.DbFile is required.
-sqlitecache_connection_failed = TSqliteCache database connection failed. {0}.
-sqlitecache_table_creation_failed = TSqliteCache failed to create cache database. {0}.
-sqlitecache_dbfile_unchangeable = TSqliteCache.DbFile cannot be modified after the module is initialized.
-sqlitecache_dbfile_invalid = TSqliteCache.DbFile is invalid. Make sure it is in a proper namespace format.
-
-memcache_extension_required = TMemCache requires memcache PHP extension.
-memcache_connection_failed = TMemCache failed to connect to memcache server {0}:{1}.
-memcache_host_unchangeable = TMemCache.Host cannot be modified after the module is initialized.
-memcache_port_unchangeable = TMemCache.Port cannot be modified after the module is initialized.
-
-apccache_extension_required = TAPCCache requires APC PHP extension.
-apccache_add_unsupported = TAPCCache.add() is not supported.
-apccache_replace_unsupported = TAPCCache.replace() is not supported.
-apccache_extension_not_enabled = TAPCCache need apc.enabled = 1 in php.ini in order to work.
-apccache_extension_not_enabled_cli = TAPCCache need apc.enable_cli = 1 in php.ini in order to work with PHP from the command line.
-
-errorhandler_errortemplatepath_invalid = TErrorHandler.ErrorTemplatePath '{0}' is invalid. Make sure it is in namespace form and points to a valid directory containing error template files.
-
-pageservice_page_unknown = Page '{0}' Not Found
-pageservice_pageclass_unknown = Page class '{0}' is unknown.
-pageservice_basepath_invalid = TPageService.BasePath '{0}' is not a valid directory.
-pageservice_page_required = Page Name Required
-pageservice_defaultpage_unchangeable = TPageService.DefaultPage cannot be modified after the service is initialized.
-pageservice_basepath_unchangeable = TPageService.BasePath cannot be modified after the service is initialized.
-pageservice_pageclass_invalid = Page class {0} is invalid. It should be TPage or extend from TPage.
-pageservice_includefile_invalid = Unable to find page service configuration {0}. Make sure it is in namespace format and the file ends with ".xml".
-
-pageserviceconf_file_invalid = Unable to open page directory configuration file '{0}'.
-pageserviceconf_aliaspath_invalid = <alias id="{0}"> uses an invalid file path "{1}" in page directory configuration file '{2}'.
-pageserviceconf_alias_invalid = <alias> element must have an "id" attribute and a "path" attribute in page directory configuration file '{0}'.
-pageserviceconf_using_invalid = <using> element must have a "namespace" attribute in page directory configuration file '{0}'.
-pageserviceconf_module_invalid = <module> element must have an "id" attribute in page directory configuration file '{0}'.
-pageserviceconf_moduletype_required = <module id="{0}"> must have a "class" attribute in page directory configuration file '{1}'.
-pageserviceconf_parameter_invalid = <parameter> element must have an "id" attribute in page directory configuration file '{0}'.
-pageserviceconf_page_invalid = <page> element must have an "id" attribute in page directory configuration file '{0}'.
-pageserviceconf_includefile_required = Page configuration <include> element must have a "file" attribute.
-
-template_closingtag_unexpected = Unexpected closing tag '{0}' is found.
-template_closingtag_expected = Closing tag '{0}' is expected.
-template_directive_nonunique = Directive '<%@ ... %>' must appear at the beginning of the template and can appear at most once.
-template_comments_forbidden = Template comments are not allowed within property tags.
-template_matching_unexpected = Unexpected matching.
-template_property_unknown = {0} has no property called '{1}'.
-template_event_unknown = {0} has no event called '{1}'.
-template_property_readonly = {0} has a read-only property '{1}'.
-template_event_forbidden = {0} is a non-control component. No handler can be attached to its event '{1}' in a template.
-template_databind_forbidden = {0} is a non-control component. Expressions cannot be bound to its property '{1}'.
-template_component_required = '{0}' is not a component. Only components can appear in a template.
-template_format_invalid = Invalid template syntax: {0}
-template_property_duplicated = Property {0} is configured twice or more.
-template_eventhandler_invalid = {0}.{1} can only accept a static string.
-template_controlid_invalid = {0}.ID can only accept a static text string.
-template_controlskinid_invalid = {0}.SkinID can only accept a static text string.
-template_content_unexpected = Unexpected content is encountered when instantiating template: {0}.
-template_include_invalid = Invalid template inclusion. Make sure {0} is a valid namespace pointing to an existing template file whose extension is .tpl.
-template_tag_unexpected = Initialization for property {0} contains an unknown tag type {1}.
-
-xmldocument_file_read_failed = TXmlDocument is unable to read file '{0}'.
-xmldocument_file_write_failed = TXmlDocument is unable to write file '{0}'.
-
-xmlelementlist_xmlelement_required = TXmlElementList can only accept TXmlElement objects.
-
-authorizationrule_action_invalid = TAuthorizationRule.Action can only take 'allow' or 'deny' as the value.
-authorizationrule_verb_invalid = TAuthorizationRule.Verb can only take 'get' or 'post' as the value.
-
-authorizationrulecollection_authorizationrule_required = TAuthorizationRuleCollection can only accept TAuthorizationRule objects.
-
-usermanager_userfile_invalid = TUserManager.UserFile '{0}' is not a valid file.
-usermanager_userfile_unchangeable = TUserManager.UserFile cannot be modified. The user module has been initialized already.
-
-authmanager_usermanager_required = TAuthManager.UserManager must be assigned a value.
-authmanager_usermanager_inexistent = TAuthManager.UserManager '{0}' does not refer to an ID of application module.
-authmanager_usermanager_invalid = TAuthManager.UserManager '{0}' does not refer to a valid TUserManager application module.
-authmanager_usermanager_unchangeable = TAuthManager.UserManager cannot be modified after the module is initialized.
-authmanager_session_required = TAuthManager requires a session application module.
-
-thememanager_service_unavailable = TThemeManager requires TPageService to be available. This error often occurs when you configure TThemeManager outside of the page service configuration.
-thememanager_basepath_invalid = TThemeManager.BasePath '{0}' is not a valid path alias. Make sure you have defined this alias in configuration and it points to a valid directory.
-thememanager_basepath_invalid2 = TThemeManager.BasePath '{0}' is not a valid directory.
-thememanager_basepath_unchangeable = TThemeManager.BasePath cannot be modified after the module is initialized.
-
-theme_baseurl_required = TThemeManager.BasePath is required. By default, a directory named 'themes' under the directory containing the application entry script is assumed.
-theme_path_inexistent = Theme path '{0}' does not exist.
-theme_control_nested = Skin for control type '{0}' in theme '{1}' cannot be within another skin.
-theme_skinid_duplicated = SkinID '{0}.{1}' is duplicated in theme '{2}'.
-theme_databind_forbidden = Databind cannot be used in theme '{0}' for control skin '{1}.{2}' about property '{3}'.
-theme_property_readonly = Skin is being applied to a read-only control property '{0}.{1}'.
-theme_property_undefined = Skin is being applied to an inexistent control property '{0}.{1}'.
-theme_tag_unexpected = Initialization for property {0} contains an unknown tag type {1}.
-
-control_object_reregistered = Duplicated object ID '{0}' found.
-control_id_invalid = {0}.ID '{1}' is invalid. Only alphanumeric and underline characters are allowed. The first character must be an alphabetic or underline character.
-control_skinid_unchangeable = {0}.SkinID cannot be modified after a skin has been applied to the control or the child controls have been created.
-control_enabletheming_unchangeable = {0}.EnableTheming cannot be modified after the child controls have been created.
-control_stylesheet_applied = StyleSheet skin has already been applied to {0}.
-control_id_nonunique = {0}.ID '{1}' is not unique among all controls under the same naming container.
-
-templatecontrol_mastercontrol_invalid = Master control must be of type TTemplateControl or a child class.
-templatecontrol_mastercontrol_required = Control '{0}' requires a master control since the control uses TContent.
-templatecontrol_contentid_duplicated = TContent ID '{0}' is duplicated.
-templatecontrol_placeholderid_duplicated= TContentPlaceHolder ID '{0}' is duplicated.
-templatecontrol_directive_invalid = {0}.{1} can only accept a static text string through a template directive.
-templatecontrol_placeholder_inexistent = TContent '{0}' does not have a matching TContentPlaceHolder.
-
-page_form_duplicated = A page can contain at most one TForm. Use regular HTML form tags for the rest forms.
-page_isvalid_unknown = TPage.IsValid has not been evaluated yet.
-page_postbackcontrol_invalid = Unable to determine postback control '{0}'.
-page_control_outofform = {0} '{1}' must be enclosed within TForm.
-page_head_duplicated = A page can contain at most one THead.
-page_head_required = A THead control is needed in page template in order to render CSS and js in the HTML head section.
-page_statepersister_invalid = Page state persister must implement IPageStatePersister interface.
-
-csmanager_pradoscript_invalid = Unknown Prado script library name '{0}'.
-csmanager_invalid_packages = Unkownn packages '{1}' for javascript packages defined in '{0}'. Valid packages are '{2}'.
-
-contentplaceholder_id_required = TContentPlaceHolder must have an ID.
-
-content_id_required = TContent must have an ID.
-
-controlcollection_control_required = TControlList can only accept strings or TControl objects.
-
-webcontrol_accesskey_invalid = {0}.AccessKey '{1}' is invalid. It must be a single character only.
-webcontrol_style_invalid = {0}.Style must take string value only.
-
-listcontrol_selection_invalid = {0} has an invalid selection that is set before performing databinding.
-listcontrol_selectedindex_invalid = {0}.SelectedIndex has an invalid value {1}.
-listcontrol_selectedvalue_invalid = {0}.SelectedValue has an invalid value '{1}'.
-listcontrol_expression_invalid = {0} is evaluating an invalid expression '{1}' : {2}
-listcontrol_multiselect_unsupported = {0} does not support multiselection.
-
-label_associatedcontrol_invalid = TLabel.AssociatedControl '{0}' cannot be found.
-
-hiddenfield_focus_unsupported = THiddenField does not support setting input focus.
-hiddenfield_theming_unsupported = THiddenField does not support theming.
-hiddenfield_skinid_unsupported = THiddenField does not support control skin.
-
-panel_defaultbutton_invalid = TPanel.DefaultButton '{0}' does not refer to an existing button control.
-
-tablestyle_cellpadding_invalid = TTableStyle.CellPadding must take an integer equal to or greater than -1.
-tablestyle_cellspacing_invalid = TTableStyle.CellSpacing must take an integer equal to or greater than -1.
-
-pagestatepersister_pagestate_corrupted = Page state is corrupted.
-
-sessionpagestatepersister_pagestate_corrupted = Page state is corrupted.
-sessionpagestatepersister_historysize_invalid = TSessionPageStatePersister.History must be an integer greater than 0.
-
-listitemcollection_item_invalid = TListItemCollection can only take strings or TListItem objects.
-
-dropdownlist_selectedindices_unsupported= TDropDownList.SelectedIndices is read-only.
-
-bulletedlist_autopostback_unsupported = TBulletedList.AutoPostBack is read-only.
-bulletedlist_selectedindex_unsupported = TBulletedList.SelectedIndex is read-only.
-bulletedlist_selectedindices_unsupported= TBulletedList.SelectedIndices is read-only.
-bulletedlist_selectedvalue_unsupported = TBulletedList.SelectedValue is read-only.
-
-radiobuttonlist_selectedindices_unsupported = TRadioButtonList.SelectedIndices is read-only.
-
-logrouter_configfile_invalid = TLogRouter.ConfigFile '{0}' does not exist.
-logrouter_routeclass_required = Class attribute is required in <route> configuration.
-logrouter_routetype_required = Log route must be an instance of TLogRoute or its derived class.
-
-filelogroute_logpath_invalid = TFileLogRoute.LogPath '{0}' must be a directory in namespace format and must be writable by the Web server process.
-filelogroute_maxfilesize_invalid = TFileLogRoute.MaxFileSize must be greater than 0.
-filelogroute_maxlogfiles_invalid = TFileLogRoute.MaxLogFiles must be greater than 0.
-
-emaillogroute_sentfrom_required = TEmailLogRoute.SentFrom cannot be empty.
-
-repeatinfo_repeatcolumns_invalid = TRepeatInfo.RepeatColumns must be no less than 0.
-
-basevalidator_controltovalidate_invalid = {0}.ControlToValidate is empty or contains an invalid control ID path.
-basevalidator_validatable_required = {0}.ControlToValidate must point to a control implementing IValidatable interface.
-basevalidator_forcontrol_unsupported = {0}.ForControl is not supported.
-
-comparevalidator_controltocompare_invalid = TCompareValidator.ControlToCompare contains an invalid control ID path.
-
-listcontrolvalidator_invalid_control = {0}.ControlToValidate contains an invalid TListControl ID path, "{1}" is a {2}.
-
-repeater_template_required = TRepeater.{0} requires a template instance implementing ITemplate interface.
-repeater_itemtype_unknown = Unknow repeater item type {0}.
-repeateritemcollection_item_invalid = TRepeaterItemCollection can only accept objects that are instance of TControl or its descendant class.
-
-datalist_template_required = TDataList.{0} requires a template instance implementing ITemplate interface.
-datalistitemcollection_datalistitem_required = TDataListItemCollection can only accept TDataListItem objects.
-
-datagrid_template_required = TDataGrid.{0} requires a template instance implementing ITemplate interface.
-templatecolumn_template_required = TTemplateColumn.{0} requires a template instance implementing ITemplate interface.
-datagrid_currentpageindex_invalid = TDataGrid.CurrentPageIndex must be no less than 0.
-datagrid_pagesize_invalid = TDataGrid.PageSize must be greater than 0.
-datagrid_virtualitemcount_invalid = TDataGrid.VirtualItemCount must be no less than 0.
-datagriditemcollection_datagriditem_required = TDataGridItemCollection can only accept TDataGridItem objects.
-datagridcolumncollection_datagridcolumn_required = TDataGridColumnCollection can only accept TDataGridColumn objects.
-datagridpagerstyle_pagebuttoncount_invalid = TDataGridPagerStyle.PageButtonCount must be greater than 0.
-
-datafieldaccessor_data_invalid = TDataFieldAccessor is trying to evaluate a field value of an invalid data. Make sure the data is an array, TMap, TList, or object that contains the specified field '{0}'.
-datafieldaccessor_datafield_invalid = TDataFieldAccessor is trying to evaluate data value of an unknown field '{0}'.
-
-tablerowcollection_tablerow_required = TTableRowCollection can only accept TTableRow objects.
-
-tablecellcollection_tablerow_required = TTableCellCollection can only accept TTableCell objects.
-
-multiview_view_required = TMultiView can only accept TView as child.
-multiview_activeviewindex_invalid = TMultiView.ActiveViewIndex has an invalid index '{0}'.
-multiview_view_inexistent = TMultiView cannot find the specified view.
-multiview_viewid_invalid = TMultiView cannot find the view '{0}' to switch to.
-
-viewcollection_view_required = TViewCollection can only accept TView as its element.
-
-view_visible_readonly = TView.Visible is read-only. Use TView.Active to toggle its visibility.
-
-wizard_step_invalid = The step to be activated cannot be found in wizard step collection.
-wizard_command_invalid = Invalid wizard navigation command '{0}'.
-
-table_tablesection_outoforder = TTable table sections must be in the order of: Header, Body and Footer.
-
-completewizardstep_steptype_readonly = TCompleteWizardStep.StepType is read-only.
-
-wizardstepcollection_wizardstep_required = TWizardStepCollection can only accept objects of TWizardStep or its derived classes.
-
-texthighlighter_stylesheet_invalid = Unable to find the stylesheet file for TTextHighlighter.
-
-hotspotcollection_hotspot_required = THotSpotCollection can only accept instance of THotSpot or its derived classes.
-
-htmlarea_textmode_readonly = THtmlArea.TextMode is read-only.
-htmlarea_tarfile_invalid = THtmlArea is unable to locate the TinyMCE tar file.
-
-parametermodule_parameterfile_unchangeable = TParameterModule.ParameterFile is not changeable because the module is already initialized.
-parametermodule_parameterfile_invalid = TParameterModule.ParameterFile '{0}' is invalid. Make sure it is in namespace format and the file extension is '.xml'.
-parametermodule_parameterid_required = Parameter element must have 'id' attribute.
-
-datagridcolumn_id_invalid = {0}.ID '{1}' is invalid. Only alphanumeric and underline characters are allowed. The first character must be an alphabetic or underline character.
-datagridcolumn_expression_invalid = {0} is evaluating an invalid expression '{1}' : {2}
-
-outputcache_cachemoduleid_invalid = TOutputCache.CacheModuleID is set with an invalid cache module ID {0}. Either the module does not exist or does not implement ICache interface.
-outputcache_duration_invalid = {0}.Duration must be an integer no less than 0.
-
-stack_data_not_iterable = TStack can only fetch data from an array or a traversable object.
-stack_empty = TStack is empty.
-
-queue_data_not_iterable = TQueue can only fetch data from an array or a traversable object.
-queue_empty = TQueue is empty.
-
-pager_pagebuttoncount_invalid = TPager.PageButtonCount must be an integer no less than 1.
-pager_currentpageindex_invalid = TPager.CurrentPageIndex is out of range.
-pager_pagecount_invalid = TPager.PageCount cannot be smaller than 0.
-pager_controltopaginate_invalid = TPager.ControlToPaginate {0} must be a valid ID path pointing to a TDataBoundControl-derived control.
-
-databoundcontrol_pagesize_invalid = {0}.PageSize must be an integer no smaller than 1.
-databoundcontrol_virtualitemcount_invalid = {0}.VirtualItemCount must be an integer no smaller than 0.
-databoundcontrol_currentpageindex_invalid = {0}.CurrentPageIndex is out of range.
-databoundcontrol_datasource_invalid = {0}.DataSource is not valid.
-databoundcontrol_datasourceid_inexistent = databoundcontrol_datasourceid_inexistent.
-databoundcontrol_datasourceid_invalid = databoundcontrol_datasourceid_invalid
-databoundcontrol_datamember_invalid = databoundcontrol_datamember_invalid
-
-clientscript_invalid_file_position = Invalid file position '{1}' for TClientScript control '{0}', must be 'Head', 'Here' or 'Begin'.
-clientscript_invalid_package_path = Invalid PackagePath '{0}' for TClientScript control '{1}'.
-
-tdatepicker_autopostback_unsupported = '{0}' does not support AutoPostBack.
-globalization_cache_path_failed = Unable to create translation message cache path '{0}'. Make sure the parent directory exists and is writable by the Web process.
-globalization_source_path_failed = Unable to create translation message path '{0}'. Make sure the parent directory exists and is writable by the Web process.
-callback_not_support_no_priority_state_update = Callback request does not support unprioritized pagestate update.
-callback_invalid_callback_options = '{1}' is not a valid TCallbackOptions control for Callback control '{0}'.
-callback_invalid_clientside_options = Callback ClientSide property must be either a string that is the ID of a TCallbackOptions control or an instance of TCallbackClientSideOptions.=======
-callback_not_support_no_priority_state_update = Callback request does not support unprioritized pagestate update.
-callback_invalid_handler = Invalid callback handler, control {0} must implement ICallbackEventHandler.
-callback_invalid_target = Invalid callback target, no such control with ID {0}.
-
-callback_interval_be_positive = Interval for TCallbackTimer "{0}" must be strictly greater than zero seconds.
-callback_decay_be_not_negative = Decay rate for TCallbackTimer "{0}" must be not negative.
-
-callback_no_autopostback = Control "{0}" can not enable AutoPostBack.
-
-xmltransform_xslextension_required = TXmlTransform requires the PHP's XSL extension.
-xmltransform_transformpath_invalid = TXmlTransform.TransformPath '{0}' is invalid.
-xmltransform_documentpath_invalid = TXmlTransform.DocumentPath '{0}' is invalid.
-xmltransform_transform_required = Either TransformContent or TransformPath property must be set for TXmlTransform.
-
-ttriggeredcallback_invalid_controlid = ControlID property for '{0}' must not be empty.
-tactivecustomvalidator_clientfunction_unsupported = {0} does not support client side validator function.
-
-dbconnection_open_failed = TDbConnection failed to establish DB connection: {0}
-dbconnection_connection_inactive = TDbConnection is inactive.
-
-dbcommand_prepare_failed = TDbCommand failed to prepare the SQL statement "{1}": {0}
-dbcommand_execute_failed = TDbCommand failed to execute the SQL statement "{1}": {0}
-dbcommand_query_failed = TDbCommand failed to execute the query SQL "{1}": {0}
-dbcommand_column_empty = TDbCommand returned an empty result and could not obtain the scalar.
-dbdatareader_rewind_invalid = TDbDataReader is a forward-only stream. It can only be traversed once.
-dbtransaction_transaction_inactive = TDbTransaction is inactive.
-
-dbcommandbuilder_value_must_not_be_null = Property {0} must not be null as defined by column '{2}' in table '{1}'.
-
-dbcommon_invalid_table_name = Database table '{0}' not found. Error message: {1}.
-dbcommon_invalid_identifier_name = Invalid database identifier name '{0}', see {1} for details.
-dbtableinfo_invalid_column_name = Invalid column name '{0}' for database table '{1}'.
-dbmetadata_invalid_table_view = Invalid table/view name '{0}', or that table/view '{0}' contains no accessible column/field definitions.
-dbmetadata_requires_php_version = PHP version {1} or later is required for using {0} database.
-
-dbtablegateway_invalid_criteria = Invalid criteria object, must be a string or instance of TSqlCriteria.
-dbtablegateway_no_primary_key_found = Table '{0}' does not contain any primary key fields.
-dbtablegateway_missing_pk_values = Missing primary key values in forming IN(key1, key2, ...) for table '{0}'.
-dbtablegateway_pk_value_count_mismatch = Composite key value count mismatch in forming IN( (key1, key2, ..), (key3, key4, ..)) for table '{0}'.
-dbtablegateway_mismatch_args_exception = TTableGateway finder method '{0}' expects {1} parameters but found only {2} parameters instead.
-dbtablegateway_mismatch_column_name = In dynamic __call() method '{0}', no matching columns were found, valid columns for table '{2}' are '{1}'.
-dbtablegateway_invalid_table_info = Table must be a string or an instanceof TDbTableInfo.
-
-directorycachedependency_directory_invalid = TDirectoryCacheDependency.Directory {0} does not refer to a valid directory.
-cachedependencylist_cachedependency_required = Only objects implementing ICacheDependency can be added into TCacheDependencyList.
-
-soapservice_configfile_invalid = TSoapService.ConfigFile '{0}' does not exist. Note, it has to be specified in a namespace format and the file extension must be '.xml'.
-soapservice_request_invalid = SOAP server '{0}' not found.
-soapservice_serverid_required = <soap> element must have 'id' attribute.
-soapservice_serverid_duplicated = SOAP server ID '{0}' is duplicated.
-soapserver_id_invalid = Invalid SOAP server ID '{0}'. It should not end with '.wsdl'.
-soapserver_version_invalid = Invalid SOAP version '{0}'. It must be either '1.1' or '1.2'.
-
-dbusermanager_userclass_required = TDbUserManager.UserClass is required.
-dbusermanager_userclass_invalid = TDbUserManager.UserClass '{0}' is not a valid user class. The class must extend TDbUser.
-dbusermanager_connectionid_invalid = TDbUserManager.ConnectionID '{0}' does not point to a valid TDataSourceConfig module.
-dbusermanager_connectionid_required = TDbUserManager.ConnectionID is required.
-
-feedservice_id_required = TFeedService requires 'id' attribute in its feed elements.
-feedservice_feedtype_invalid = The class feed '{0}' must implement IFeedContentProvider interface.
-feedservice_class_required = TFeedService requires 'class' attribute in its feed elements.
-feedservice_feed_unknown = Unknown feed '{0}' requested.
-
-tabviewcollection_tabview_required = TTabPanel can only accept TTabView as child.
-tabpanel_activeviewid_invalid = TTabPanel.ActiveViewID has an invalid ID '{0}'.
-tabpanel_activeviewindex_invalid = TTabPanel.ActiveViewIndex has an invalid Index '{0}'.
-tabpanel_view_inexistent = TTabPanel cannot find the specified view.
-
-cachesession_cachemoduleid_required = TCacheHttpSession.CacheModuleID is required.
-cachesession_cachemodule_inexistent = TCacheHttpSession.CacheModuleID '{0}' points to a non-existent module.
-cachesession_cachemodule_invalid = TCacheHttpSession.CacheModuleID '{0}' points to a module that does not implement ICache interface.
-
-urlmapping_urlmappingpattern_required = TUrlMapping can only contain TUrlMappingPattern or its child classes.
+prado_application_singleton_required = Prado.Application must only be set once.
+prado_component_unknown = Unknown component type '{0}'. This may be caused by following parsing error in the {0} class file: {1}
+prado_using_invalid = '{0}' is not a valid namespace to be used. Make sure '.*' is appended if you want to use a namespace referring to a directory.
+prado_alias_redefined = Alias '{0}' cannot be redefined.
+prado_alias_invalid = Alias '{0}' refers to an invalid path '{1}'. Only existing directories can be aliased.
+prado_aliasname_invalid = Alias '{0}' contains invalid character '.'.
+
+component_property_undefined = Component property '{0}.{1}' is not defined.
+component_property_readonly = Component property '{0}.{1}' is read-only.
+component_event_undefined = Component event '{0}.{1}' is not defined.
+component_eventhandler_invalid = Component event '{0}.{1}' is attached with an invalid event handler '{2}'.
+component_expression_invalid = Component '{0}' is evaluating an invalid expression '{1}' : {2}.
+component_statements_invalid = Component '{0}' is evaluating invalid PHP statements '{1}' : {2}.
+
+propertyvalue_enumvalue_invalid = Value '{0}' is a not valid enumeration value ({1}).
+
+list_index_invalid = Index '{0}' is out of range.
+list_item_inexistent = The item cannot be found in the list.
+list_data_not_iterable = Data must be either an array or an object implementing Traversable interface.
+list_readonly = {0} is read-only.
+
+map_addition_disallowed = The new item cannot be added to the map.
+map_item_unremovable = The item cannot be removed from the map.
+map_data_not_iterable = Data must be either an array or an object implementing Traversable interface.
+map_readonly = {0} is read-only.
+
+application_includefile_invalid = Unable to find application configuration {0}. Make sure it is in namespace format and the file ends with ".xml".
+application_basepath_invalid = Application base path '{0}' does not exist or is not a directory.
+application_runtimepath_invalid = Application runtime path '{0}' does not exist or is not writable by Web server process.
+application_service_invalid = Service '{0}' must implement IService interface.
+application_service_unknown = Requested service '{0}' is not defined.
+application_unavailable = Application is unavailable at this time.
+application_service_unavailable = Service '{0}' is unavailable at this time.
+application_moduleid_duplicated = Application module ID '{0}' is not unique.
+application_runtimepath_failed = Unable to create runtime path '{0}'. Make sure the parent directory exists and is writable by the Web process.
+
+appconfig_aliaspath_invalid = Application configuration <alias id="{0}"> uses an invalid file path "{1}".
+appconfig_alias_invalid = Application configuration <alias> element must have an "id" attribute and a "path" attribute.
+appconfig_alias_redefined = Application configuration <alias id="{0}"> cannot be redefined.
+appconfig_using_invalid = Application configuration <using> element must have a "namespace" attribute.
+appconfig_moduleid_required = Application configuration <module> element must have an "id" attribute.
+appconfig_moduletype_required = Application configuration <module id="{0}"> must have a "class" attribute.
+appconfig_serviceid_required = Application configuration <service> element must have an "id" attribute.
+appconfig_servicetype_required = Application configuration <service id="{0}"> must have a "class" attribute.
+appconfig_parameterid_required = Application configuration <parameter> element must have an "id" attribute.
+appconfig_includefile_required = Application configuration <include> element must have a "file" attribute.
+
+securitymanager_validationkey_invalid = TSecurityManager.ValidationKey must not be empty.
+securitymanager_encryptionkey_invalid = TSecurityManager.EncryptionKey must not be empty.
+securitymanager_mcryptextension_required = Mcrypt PHP extension is required in order to use TSecurityManager's encryption feature.
+
+uri_format_invalid = '{0}' is not a valid URI.
+
+httprequest_separator_invalid = THttpRequest.UrlParamSeparator can only contain a single character.
+httprequest_urlmanager_inexist = THttpRequest.UrlManager '{0}' does not point to an existing module.
+httprequest_urlmanager_invalid = THttpRequest.UrlManager '{0}' must point to a module extending from TUrlManager.
+
+httpcookiecollection_httpcookie_required = THttpCookieCollection can only accept THttpCookie objects.
+
+httpresponse_bufferoutput_unchangeable = THttpResponse.BufferOutput cannot be modified after THttpResponse is initialized.
+httpresponse_file_inexistent = THttpResponse cannot send file '{0}'. The file does not exist.
+
+httpsession_sessionid_unchangeable = THttpSession.SessionID cannot be modified after the session is started.
+httpsession_sessionname_unchangeable = THttpSession.SessionName cannot be modified after the session is started.
+httpsession_sessionname_invalid = THttpSession.SessionName must contain alphanumeric characters only.
+httpsession_savepath_unchangeable = THttpSession.SavePath cannot be modified after the session is started.
+httpsession_savepath_invalid = THttpSession.SavePath '{0}' is invalid.
+httpsession_storage_unchangeable = THttpSession.Storage cannot be modified after the session is started.
+httpsession_cookiemode_unchangeable = THttpSession.CookieMode cannot be modified after the session is started.
+httpsession_autostart_unchangeable = THttpSession.AutoStart cannot be modified after the session module is initialized.
+httpsession_gcprobability_unchangeable = THttpSession.GCProbability cannot be modified after the session is started.
+httpsession_gcprobability_invalid = THttpSession.GCProbability must be an integer between 0 and 100.
+httpsession_transid_unchangeable = THttpSession.UseTransparentSessionID cannot be modified after the session is started.
+httpsession_maxlifetime_unchangeable = THttpSession.Timeout cannot be modified after the session is started.
+
+assetmanager_basepath_invalid = TAssetManager.BasePath '{0}' is invalid. Make sure it is in namespace form and points to a directory writable by the Web server process.
+assetmanager_basepath_unchangeable = TAssetManager.BasePath cannot be modified after the module is initialized.
+assetmanager_baseurl_unchangeable = TAssetManager.BaseUrl cannot be modified after the module is initialized.
+assetmanager_filepath_invalid = TAssetManager is publishing an invalid file '{0}'.
+assetmanager_tarchecksum_invalid = TAssetManager is publishing a tar file with invalid checksum '{0}'.
+assetmanager_tarfile_invalid = TAssetManager is publishing an invalid tar file '{0}'.
+assetmanager_source_directory_invalid = TAssetManager is copying an invalid directory '{0}'.
+
+cache_primary_duplicated = At most one primary cache module is allowed. {0} is trying to register as another primary cache.
+sqlitecache_extension_required = TSqliteCache requires SQLite PHP extension.
+sqlitecache_dbfile_required = TSqliteCache.DbFile is required.
+sqlitecache_connection_failed = TSqliteCache database connection failed. {0}.
+sqlitecache_table_creation_failed = TSqliteCache failed to create cache database. {0}.
+sqlitecache_dbfile_unchangeable = TSqliteCache.DbFile cannot be modified after the module is initialized.
+sqlitecache_dbfile_invalid = TSqliteCache.DbFile is invalid. Make sure it is in a proper namespace format.
+
+memcache_extension_required = TMemCache requires memcache PHP extension.
+memcache_connection_failed = TMemCache failed to connect to memcache server {0}:{1}.
+memcache_host_unchangeable = TMemCache.Host cannot be modified after the module is initialized.
+memcache_port_unchangeable = TMemCache.Port cannot be modified after the module is initialized.
+
+apccache_extension_required = TAPCCache requires APC PHP extension.
+apccache_add_unsupported = TAPCCache.add() is not supported.
+apccache_replace_unsupported = TAPCCache.replace() is not supported.
+apccache_extension_not_enabled = TAPCCache need apc.enabled = 1 in php.ini in order to work.
+apccache_extension_not_enabled_cli = TAPCCache need apc.enable_cli = 1 in php.ini in order to work with PHP from the command line.
+
+errorhandler_errortemplatepath_invalid = TErrorHandler.ErrorTemplatePath '{0}' is invalid. Make sure it is in namespace form and points to a valid directory containing error template files.
+
+pageservice_page_unknown = Page '{0}' Not Found
+pageservice_pageclass_unknown = Page class '{0}' is unknown.
+pageservice_basepath_invalid = TPageService.BasePath '{0}' is not a valid directory.
+pageservice_page_required = Page Name Required
+pageservice_defaultpage_unchangeable = TPageService.DefaultPage cannot be modified after the service is initialized.
+pageservice_basepath_unchangeable = TPageService.BasePath cannot be modified after the service is initialized.
+pageservice_pageclass_invalid = Page class {0} is invalid. It should be TPage or extend from TPage.
+pageservice_includefile_invalid = Unable to find page service configuration {0}. Make sure it is in namespace format and the file ends with ".xml".
+
+pageserviceconf_file_invalid = Unable to open page directory configuration file '{0}'.
+pageserviceconf_aliaspath_invalid = <alias id="{0}"> uses an invalid file path "{1}" in page directory configuration file '{2}'.
+pageserviceconf_alias_invalid = <alias> element must have an "id" attribute and a "path" attribute in page directory configuration file '{0}'.
+pageserviceconf_using_invalid = <using> element must have a "namespace" attribute in page directory configuration file '{0}'.
+pageserviceconf_module_invalid = <module> element must have an "id" attribute in page directory configuration file '{0}'.
+pageserviceconf_moduletype_required = <module id="{0}"> must have a "class" attribute in page directory configuration file '{1}'.
+pageserviceconf_parameter_invalid = <parameter> element must have an "id" attribute in page directory configuration file '{0}'.
+pageserviceconf_page_invalid = <page> element must have an "id" attribute in page directory configuration file '{0}'.
+pageserviceconf_includefile_required = Page configuration <include> element must have a "file" attribute.
+
+template_closingtag_unexpected = Unexpected closing tag '{0}' is found.
+template_closingtag_expected = Closing tag '{0}' is expected.
+template_directive_nonunique = Directive '<%@ ... %>' must appear at the beginning of the template and can appear at most once.
+template_comments_forbidden = Template comments are not allowed within property tags.
+template_matching_unexpected = Unexpected matching.
+template_property_unknown = {0} has no property called '{1}'.
+template_event_unknown = {0} has no event called '{1}'.
+template_property_readonly = {0} has a read-only property '{1}'.
+template_event_forbidden = {0} is a non-control component. No handler can be attached to its event '{1}' in a template.
+template_databind_forbidden = {0} is a non-control component. Expressions cannot be bound to its property '{1}'.
+template_component_required = '{0}' is not a component. Only components can appear in a template.
+template_format_invalid = Invalid template syntax: {0}
+template_property_duplicated = Property {0} is configured twice or more.
+template_eventhandler_invalid = {0}.{1} can only accept a static string.
+template_controlid_invalid = {0}.ID can only accept a static text string.
+template_controlskinid_invalid = {0}.SkinID can only accept a static text string.
+template_content_unexpected = Unexpected content is encountered when instantiating template: {0}.
+template_include_invalid = Invalid template inclusion. Make sure {0} is a valid namespace pointing to an existing template file whose extension is .tpl.
+template_tag_unexpected = Initialization for property {0} contains an unknown tag type {1}.
+
+xmldocument_file_read_failed = TXmlDocument is unable to read file '{0}'.
+xmldocument_file_write_failed = TXmlDocument is unable to write file '{0}'.
+
+xmlelementlist_xmlelement_required = TXmlElementList can only accept TXmlElement objects.
+
+authorizationrule_action_invalid = TAuthorizationRule.Action can only take 'allow' or 'deny' as the value.
+authorizationrule_verb_invalid = TAuthorizationRule.Verb can only take 'get' or 'post' as the value.
+
+authorizationrulecollection_authorizationrule_required = TAuthorizationRuleCollection can only accept TAuthorizationRule objects.
+
+usermanager_userfile_invalid = TUserManager.UserFile '{0}' is not a valid file.
+usermanager_userfile_unchangeable = TUserManager.UserFile cannot be modified. The user module has been initialized already.
+
+authmanager_usermanager_required = TAuthManager.UserManager must be assigned a value.
+authmanager_usermanager_inexistent = TAuthManager.UserManager '{0}' does not refer to an ID of application module.
+authmanager_usermanager_invalid = TAuthManager.UserManager '{0}' does not refer to a valid TUserManager application module.
+authmanager_usermanager_unchangeable = TAuthManager.UserManager cannot be modified after the module is initialized.
+authmanager_session_required = TAuthManager requires a session application module.
+
+thememanager_service_unavailable = TThemeManager requires TPageService to be available. This error often occurs when you configure TThemeManager outside of the page service configuration.
+thememanager_basepath_invalid = TThemeManager.BasePath '{0}' is not a valid path alias. Make sure you have defined this alias in configuration and it points to a valid directory.
+thememanager_basepath_invalid2 = TThemeManager.BasePath '{0}' is not a valid directory.
+thememanager_basepath_unchangeable = TThemeManager.BasePath cannot be modified after the module is initialized.
+
+theme_baseurl_required = TThemeManager.BasePath is required. By default, a directory named 'themes' under the directory containing the application entry script is assumed.
+theme_path_inexistent = Theme path '{0}' does not exist.
+theme_control_nested = Skin for control type '{0}' in theme '{1}' cannot be within another skin.
+theme_skinid_duplicated = SkinID '{0}.{1}' is duplicated in theme '{2}'.
+theme_databind_forbidden = Databind cannot be used in theme '{0}' for control skin '{1}.{2}' about property '{3}'.
+theme_property_readonly = Skin is being applied to a read-only control property '{0}.{1}'.
+theme_property_undefined = Skin is being applied to an inexistent control property '{0}.{1}'.
+theme_tag_unexpected = Initialization for property {0} contains an unknown tag type {1}.
+
+control_object_reregistered = Duplicated object ID '{0}' found.
+control_id_invalid = {0}.ID '{1}' is invalid. Only alphanumeric and underline characters are allowed. The first character must be an alphabetic or underline character.
+control_skinid_unchangeable = {0}.SkinID cannot be modified after a skin has been applied to the control or the child controls have been created.
+control_enabletheming_unchangeable = {0}.EnableTheming cannot be modified after the child controls have been created.
+control_stylesheet_applied = StyleSheet skin has already been applied to {0}.
+control_id_nonunique = {0}.ID '{1}' is not unique among all controls under the same naming container.
+
+templatecontrol_mastercontrol_invalid = Master control must be of type TTemplateControl or a child class.
+templatecontrol_mastercontrol_required = Control '{0}' requires a master control since the control uses TContent.
+templatecontrol_contentid_duplicated = TContent ID '{0}' is duplicated.
+templatecontrol_placeholderid_duplicated= TContentPlaceHolder ID '{0}' is duplicated.
+templatecontrol_directive_invalid = {0}.{1} can only accept a static text string through a template directive.
+templatecontrol_placeholder_inexistent = TContent '{0}' does not have a matching TContentPlaceHolder.
+
+page_form_duplicated = A page can contain at most one TForm. Use regular HTML form tags for the rest forms.
+page_isvalid_unknown = TPage.IsValid has not been evaluated yet.
+page_postbackcontrol_invalid = Unable to determine postback control '{0}'.
+page_control_outofform = {0} '{1}' must be enclosed within TForm.
+page_head_duplicated = A page can contain at most one THead.
+page_head_required = A THead control is needed in page template in order to render CSS and js in the HTML head section.
+page_statepersister_invalid = Page state persister must implement IPageStatePersister interface.
+
+csmanager_pradoscript_invalid = Unknown Prado script library name '{0}'.
+csmanager_invalid_packages = Unkownn packages '{1}' for javascript packages defined in '{0}'. Valid packages are '{2}'.
+
+contentplaceholder_id_required = TContentPlaceHolder must have an ID.
+
+content_id_required = TContent must have an ID.
+
+controlcollection_control_required = TControlList can only accept strings or TControl objects.
+
+webcontrol_accesskey_invalid = {0}.AccessKey '{1}' is invalid. It must be a single character only.
+webcontrol_style_invalid = {0}.Style must take string value only.
+
+listcontrol_selection_invalid = {0} has an invalid selection that is set before performing databinding.
+listcontrol_selectedindex_invalid = {0}.SelectedIndex has an invalid value {1}.
+listcontrol_selectedvalue_invalid = {0}.SelectedValue has an invalid value '{1}'.
+listcontrol_expression_invalid = {0} is evaluating an invalid expression '{1}' : {2}
+listcontrol_multiselect_unsupported = {0} does not support multiselection.
+
+label_associatedcontrol_invalid = TLabel.AssociatedControl '{0}' cannot be found.
+
+hiddenfield_focus_unsupported = THiddenField does not support setting input focus.
+hiddenfield_theming_unsupported = THiddenField does not support theming.
+hiddenfield_skinid_unsupported = THiddenField does not support control skin.
+
+panel_defaultbutton_invalid = TPanel.DefaultButton '{0}' does not refer to an existing button control.
+
+tablestyle_cellpadding_invalid = TTableStyle.CellPadding must take an integer equal to or greater than -1.
+tablestyle_cellspacing_invalid = TTableStyle.CellSpacing must take an integer equal to or greater than -1.
+
+pagestatepersister_pagestate_corrupted = Page state is corrupted.
+
+sessionpagestatepersister_pagestate_corrupted = Page state is corrupted.
+sessionpagestatepersister_historysize_invalid = TSessionPageStatePersister.History must be an integer greater than 0.
+
+listitemcollection_item_invalid = TListItemCollection can only take strings or TListItem objects.
+
+dropdownlist_selectedindices_unsupported= TDropDownList.SelectedIndices is read-only.
+
+bulletedlist_autopostback_unsupported = TBulletedList.AutoPostBack is read-only.
+bulletedlist_selectedindex_unsupported = TBulletedList.SelectedIndex is read-only.
+bulletedlist_selectedindices_unsupported= TBulletedList.SelectedIndices is read-only.
+bulletedlist_selectedvalue_unsupported = TBulletedList.SelectedValue is read-only.
+
+radiobuttonlist_selectedindices_unsupported = TRadioButtonList.SelectedIndices is read-only.
+
+logrouter_configfile_invalid = TLogRouter.ConfigFile '{0}' does not exist.
+logrouter_routeclass_required = Class attribute is required in <route> configuration.
+logrouter_routetype_required = Log route must be an instance of TLogRoute or its derived class.
+
+filelogroute_logpath_invalid = TFileLogRoute.LogPath '{0}' must be a directory in namespace format and must be writable by the Web server process.
+filelogroute_maxfilesize_invalid = TFileLogRoute.MaxFileSize must be greater than 0.
+filelogroute_maxlogfiles_invalid = TFileLogRoute.MaxLogFiles must be greater than 0.
+
+emaillogroute_sentfrom_required = TEmailLogRoute.SentFrom cannot be empty.
+
+repeatinfo_repeatcolumns_invalid = TRepeatInfo.RepeatColumns must be no less than 0.
+
+basevalidator_controltovalidate_invalid = {0}.ControlToValidate is empty or contains an invalid control ID path.
+basevalidator_validatable_required = {0}.ControlToValidate must point to a control implementing IValidatable interface.
+basevalidator_forcontrol_unsupported = {0}.ForControl is not supported.
+
+comparevalidator_controltocompare_invalid = TCompareValidator.ControlToCompare contains an invalid control ID path.
+
+listcontrolvalidator_invalid_control = {0}.ControlToValidate contains an invalid TListControl ID path, "{1}" is a {2}.
+
+repeater_template_required = TRepeater.{0} requires a template instance implementing ITemplate interface.
+repeater_itemtype_unknown = Unknow repeater item type {0}.
+repeateritemcollection_item_invalid = TRepeaterItemCollection can only accept objects that are instance of TControl or its descendant class.
+
+datalist_template_required = TDataList.{0} requires a template instance implementing ITemplate interface.
+datalistitemcollection_datalistitem_required = TDataListItemCollection can only accept TDataListItem objects.
+
+datagrid_template_required = TDataGrid.{0} requires a template instance implementing ITemplate interface.
+templatecolumn_template_required = TTemplateColumn.{0} requires a template instance implementing ITemplate interface.
+datagrid_currentpageindex_invalid = TDataGrid.CurrentPageIndex must be no less than 0.
+datagrid_pagesize_invalid = TDataGrid.PageSize must be greater than 0.
+datagrid_virtualitemcount_invalid = TDataGrid.VirtualItemCount must be no less than 0.
+datagriditemcollection_datagriditem_required = TDataGridItemCollection can only accept TDataGridItem objects.
+datagridcolumncollection_datagridcolumn_required = TDataGridColumnCollection can only accept TDataGridColumn objects.
+datagridpagerstyle_pagebuttoncount_invalid = TDataGridPagerStyle.PageButtonCount must be greater than 0.
+
+datafieldaccessor_data_invalid = TDataFieldAccessor is trying to evaluate a field value of an invalid data. Make sure the data is an array, TMap, TList, or object that contains the specified field '{0}'.
+datafieldaccessor_datafield_invalid = TDataFieldAccessor is trying to evaluate data value of an unknown field '{0}'.
+
+tablerowcollection_tablerow_required = TTableRowCollection can only accept TTableRow objects.
+
+tablecellcollection_tablerow_required = TTableCellCollection can only accept TTableCell objects.
+
+multiview_view_required = TMultiView can only accept TView as child.
+multiview_activeviewindex_invalid = TMultiView.ActiveViewIndex has an invalid index '{0}'.
+multiview_view_inexistent = TMultiView cannot find the specified view.
+multiview_viewid_invalid = TMultiView cannot find the view '{0}' to switch to.
+
+viewcollection_view_required = TViewCollection can only accept TView as its element.
+
+view_visible_readonly = TView.Visible is read-only. Use TView.Active to toggle its visibility.
+
+wizard_step_invalid = The step to be activated cannot be found in wizard step collection.
+wizard_command_invalid = Invalid wizard navigation command '{0}'.
+
+table_tablesection_outoforder = TTable table sections must be in the order of: Header, Body and Footer.
+
+completewizardstep_steptype_readonly = TCompleteWizardStep.StepType is read-only.
+
+wizardstepcollection_wizardstep_required = TWizardStepCollection can only accept objects of TWizardStep or its derived classes.
+
+texthighlighter_stylesheet_invalid = Unable to find the stylesheet file for TTextHighlighter.
+
+hotspotcollection_hotspot_required = THotSpotCollection can only accept instance of THotSpot or its derived classes.
+
+htmlarea_textmode_readonly = THtmlArea.TextMode is read-only.
+htmlarea_tarfile_invalid = THtmlArea is unable to locate the TinyMCE tar file.
+
+parametermodule_parameterfile_unchangeable = TParameterModule.ParameterFile is not changeable because the module is already initialized.
+parametermodule_parameterfile_invalid = TParameterModule.ParameterFile '{0}' is invalid. Make sure it is in namespace format and the file extension is '.xml'.
+parametermodule_parameterid_required = Parameter element must have 'id' attribute.
+
+datagridcolumn_id_invalid = {0}.ID '{1}' is invalid. Only alphanumeric and underline characters are allowed. The first character must be an alphabetic or underline character.
+datagridcolumn_expression_invalid = {0} is evaluating an invalid expression '{1}' : {2}
+
+outputcache_cachemoduleid_invalid = TOutputCache.CacheModuleID is set with an invalid cache module ID {0}. Either the module does not exist or does not implement ICache interface.
+outputcache_duration_invalid = {0}.Duration must be an integer no less than 0.
+
+stack_data_not_iterable = TStack can only fetch data from an array or a traversable object.
+stack_empty = TStack is empty.
+
+queue_data_not_iterable = TQueue can only fetch data from an array or a traversable object.
+queue_empty = TQueue is empty.
+
+pager_pagebuttoncount_invalid = TPager.PageButtonCount must be an integer no less than 1.
+pager_currentpageindex_invalid = TPager.CurrentPageIndex is out of range.
+pager_pagecount_invalid = TPager.PageCount cannot be smaller than 0.
+pager_controltopaginate_invalid = TPager.ControlToPaginate {0} must be a valid ID path pointing to a TDataBoundControl-derived control.
+
+databoundcontrol_pagesize_invalid = {0}.PageSize must be an integer no smaller than 1.
+databoundcontrol_virtualitemcount_invalid = {0}.VirtualItemCount must be an integer no smaller than 0.
+databoundcontrol_currentpageindex_invalid = {0}.CurrentPageIndex is out of range.
+databoundcontrol_datasource_invalid = {0}.DataSource is not valid.
+databoundcontrol_datasourceid_inexistent = databoundcontrol_datasourceid_inexistent.
+databoundcontrol_datasourceid_invalid = databoundcontrol_datasourceid_invalid
+databoundcontrol_datamember_invalid = databoundcontrol_datamember_invalid
+
+clientscript_invalid_file_position = Invalid file position '{1}' for TClientScript control '{0}', must be 'Head', 'Here' or 'Begin'.
+clientscript_invalid_package_path = Invalid PackagePath '{0}' for TClientScript control '{1}'.
+
+tdatepicker_autopostback_unsupported = '{0}' does not support AutoPostBack.
+globalization_cache_path_failed = Unable to create translation message cache path '{0}'. Make sure the parent directory exists and is writable by the Web process.
+globalization_source_path_failed = Unable to create translation message path '{0}'. Make sure the parent directory exists and is writable by the Web process.
+callback_not_support_no_priority_state_update = Callback request does not support unprioritized pagestate update.
+callback_invalid_callback_options = '{1}' is not a valid TCallbackOptions control for Callback control '{0}'.
+callback_invalid_clientside_options = Callback ClientSide property must be either a string that is the ID of a TCallbackOptions control or an instance of TCallbackClientSideOptions.=======
+callback_not_support_no_priority_state_update = Callback request does not support unprioritized pagestate update.
+callback_invalid_handler = Invalid callback handler, control {0} must implement ICallbackEventHandler.
+callback_invalid_target = Invalid callback target, no such control with ID {0}.
+
+callback_interval_be_positive = Interval for TCallbackTimer "{0}" must be strictly greater than zero seconds.
+callback_decay_be_not_negative = Decay rate for TCallbackTimer "{0}" must be not negative.
+
+callback_no_autopostback = Control "{0}" can not enable AutoPostBack.
+
+xmltransform_xslextension_required = TXmlTransform requires the PHP's XSL extension.
+xmltransform_transformpath_invalid = TXmlTransform.TransformPath '{0}' is invalid.
+xmltransform_documentpath_invalid = TXmlTransform.DocumentPath '{0}' is invalid.
+xmltransform_transform_required = Either TransformContent or TransformPath property must be set for TXmlTransform.
+
+ttriggeredcallback_invalid_controlid = ControlID property for '{0}' must not be empty.
+tactivecustomvalidator_clientfunction_unsupported = {0} does not support client side validator function.
+
+dbconnection_open_failed = TDbConnection failed to establish DB connection: {0}
+dbconnection_connection_inactive = TDbConnection is inactive.
+
+dbcommand_prepare_failed = TDbCommand failed to prepare the SQL statement "{1}": {0}
+dbcommand_execute_failed = TDbCommand failed to execute the SQL statement "{1}": {0}
+dbcommand_query_failed = TDbCommand failed to execute the query SQL "{1}": {0}
+dbcommand_column_empty = TDbCommand returned an empty result and could not obtain the scalar.
+dbdatareader_rewind_invalid = TDbDataReader is a forward-only stream. It can only be traversed once.
+dbtransaction_transaction_inactive = TDbTransaction is inactive.
+
+dbcommandbuilder_value_must_not_be_null = Property {0} must not be null as defined by column '{2}' in table '{1}'.
+
+dbcommon_invalid_table_name = Database table '{0}' not found. Error message: {1}.
+dbcommon_invalid_identifier_name = Invalid database identifier name '{0}', see {1} for details.
+dbtableinfo_invalid_column_name = Invalid column name '{0}' for database table '{1}'.
+dbmetadata_invalid_table_view = Invalid table/view name '{0}', or that table/view '{0}' contains no accessible column/field definitions.
+dbmetadata_requires_php_version = PHP version {1} or later is required for using {0} database.
+
+dbtablegateway_invalid_criteria = Invalid criteria object, must be a string or instance of TSqlCriteria.
+dbtablegateway_no_primary_key_found = Table '{0}' does not contain any primary key fields.
+dbtablegateway_missing_pk_values = Missing primary key values in forming IN(key1, key2, ...) for table '{0}'.
+dbtablegateway_pk_value_count_mismatch = Composite key value count mismatch in forming IN( (key1, key2, ..), (key3, key4, ..)) for table '{0}'.
+dbtablegateway_mismatch_args_exception = TTableGateway finder method '{0}' expects {1} parameters but found only {2} parameters instead.
+dbtablegateway_mismatch_column_name = In dynamic __call() method '{0}', no matching columns were found, valid columns for table '{2}' are '{1}'.
+dbtablegateway_invalid_table_info = Table must be a string or an instanceof TDbTableInfo.
+
+directorycachedependency_directory_invalid = TDirectoryCacheDependency.Directory {0} does not refer to a valid directory.
+cachedependencylist_cachedependency_required = Only objects implementing ICacheDependency can be added into TCacheDependencyList.
+
+soapservice_configfile_invalid = TSoapService.ConfigFile '{0}' does not exist. Note, it has to be specified in a namespace format and the file extension must be '.xml'.
+soapservice_request_invalid = SOAP server '{0}' not found.
+soapservice_serverid_required = <soap> element must have 'id' attribute.
+soapservice_serverid_duplicated = SOAP server ID '{0}' is duplicated.
+soapserver_id_invalid = Invalid SOAP server ID '{0}'. It should not end with '.wsdl'.
+soapserver_version_invalid = Invalid SOAP version '{0}'. It must be either '1.1' or '1.2'.
+
+dbusermanager_userclass_required = TDbUserManager.UserClass is required.
+dbusermanager_userclass_invalid = TDbUserManager.UserClass '{0}' is not a valid user class. The class must extend TDbUser.
+dbusermanager_connectionid_invalid = TDbUserManager.ConnectionID '{0}' does not point to a valid TDataSourceConfig module.
+dbusermanager_connectionid_required = TDbUserManager.ConnectionID is required.
+
+feedservice_id_required = TFeedService requires 'id' attribute in its feed elements.
+feedservice_feedtype_invalid = The class feed '{0}' must implement IFeedContentProvider interface.
+feedservice_class_required = TFeedService requires 'class' attribute in its feed elements.
+feedservice_feed_unknown = Unknown feed '{0}' requested.
+
+tabviewcollection_tabview_required = TTabPanel can only accept TTabView as child.
+tabpanel_activeviewid_invalid = TTabPanel.ActiveViewID has an invalid ID '{0}'.
+tabpanel_activeviewindex_invalid = TTabPanel.ActiveViewIndex has an invalid Index '{0}'.
+tabpanel_view_inexistent = TTabPanel cannot find the specified view.
+
+cachesession_cachemoduleid_required = TCacheHttpSession.CacheModuleID is required.
+cachesession_cachemodule_inexistent = TCacheHttpSession.CacheModuleID '{0}' points to a non-existent module.
+cachesession_cachemodule_invalid = TCacheHttpSession.CacheModuleID '{0}' points to a module that does not implement ICache interface.
+
+urlmapping_urlmappingpattern_required = TUrlMapping can only contain TUrlMappingPattern or its child classes.
urlmappingpattern_serviceparameter_required = TUrlMappingPattern.ServiceParameter is required for pattern '{0}'. \ No newline at end of file
diff --git a/framework/TComponent.php b/framework/TComponent.php
index edf72af6..5b751ff3 100644
--- a/framework/TComponent.php
+++ b/framework/TComponent.php
@@ -1,842 +1,842 @@
-<?php
-/**
- * TComponent, TPropertyValue classes
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright &copy; 2005 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System
- */
-
-/**
- * TComponent class
- *
- * TComponent is the base class for all PRADO components.
- * TComponent implements the protocol of defining, using properties and events.
- *
- * A property is defined by a getter method, and/or a setter method.
- * Properties can be accessed in the way like accessing normal object members.
- * Reading or writing a property will cause the invocation of the corresponding
- * getter or setter method, e.g.,
- * <code>
- * $a=$this->Text; // equivalent to $a=$this->getText();
- * $this->Text='abc'; // equivalent to $this->setText('abc');
- * </code>
- * The signatures of getter and setter methods are as follows,
- * <code>
- * // getter, defines a readable property 'Text'
- * function getText() { ... }
- * // setter, defines a writable property 'Text', with $value being the value to be set to the property
- * function setText($value) { ... }
- * </code>
- * Property names are case-insensitive. It is recommended that they are written
- * in the format of concatenated words, with the first letter of each word
- * capitalized (e.g. DisplayMode, ItemStyle).
- *
- * An event is defined by the presence of a method whose name starts with 'on'.
- * The event name is the method name and is thus case-insensitive.
- * An event can be attached with one or several methods (called event handlers).
- * An event can be raised by calling {@link raiseEvent} method, upon which
- * the attached event handlers will be invoked automatically in the order they
- * are attached to the event. Event handlers must have the following signature,
- * <code>
- * function eventHandlerFuncName($sender,$param) { ... }
- * </code>
- * where $sender refers to the object who is responsible for the raising of the event,
- * and $param refers to a structure that may contain event-specific information.
- * To raise an event (assuming named as 'Click') of a component, use
- * <code>
- * $component->raiseEvent('OnClick');
- * </code>
- * To attach an event handler to an event, use one of the following ways,
- * <code>
- * $component->OnClick=$callback; // or $component->OnClick->add($callback);
- * $$component->attachEventHandler('OnClick',$callback);
- * </code>
- * The first two ways make use of the fact that $component->OnClick refers to
- * the event handler list {@link TList} for the 'OnClick' event.
- * The variable $callback contains the definition of the event handler that can
- * be either a string referring to a global function name, or an array whose
- * first element refers to an object and second element a method name/path that
- * is reachable by the object, e.g.
- * - 'buttonClicked' : buttonClicked($sender,$param);
- * - array($object,'buttonClicked') : $object->buttonClicked($sender,$param);
- * - array($object,'MainContent.SubmitButton.buttonClicked') :
- * $object->MainContent->SubmitButton->buttonClicked($sender,$param);
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System
- * @since 3.0
- */
-class TComponent
-{
- /**
- * @var array event handler lists
- */
- private $_e=array();
-
- /**
- * Returns a property value or an event handler list by property or event name.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using the following syntax to read a property:
- * <code>
- * $value=$component->PropertyName;
- * </code>
- * and to obtain the event handler list for an event,
- * <code>
- * $eventHandlerList=$component->EventName;
- * </code>
- * @param string the property name or the event name
- * @return mixed the property value or the event handler list
- * @throws TInvalidOperationException if the property/event is not defined.
- */
- public function __get($name)
- {
- $getter='get'.$name;
- if(method_exists($this,$getter))
- {
- // getting a property
- return $this->$getter();
- }
- else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- {
- // getting an event (handler list)
- $name=strtolower($name);
- if(!isset($this->_e[$name]))
- $this->_e[$name]=new TList;
- return $this->_e[$name];
- }
- else
- {
- throw new TInvalidOperationException('component_property_undefined',get_class($this),$name);
- }
- }
-
- /**
- * Sets value of a component property.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using the following syntax to set a property or attach an event handler.
- * <code>
- * $this->PropertyName=$value;
- * $this->EventName=$handler;
- * </code>
- * @param string the property name or event name
- * @param mixed the property value or event handler
- * @throws TInvalidOperationException If the property is not defined or read-only.
- */
- public function __set($name,$value)
- {
- $setter='set'.$name;
- if(method_exists($this,$setter))
- {
- $this->$setter($value);
- }
- else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- {
- $this->attachEventHandler($name,$value);
- }
- else if(method_exists($this,'get'.$name))
- {
- throw new TInvalidOperationException('component_property_readonly',get_class($this),$name);
- }
- else
- {
- throw new TInvalidOperationException('component_property_undefined',get_class($this),$name);
- }
- }
-
- /**
- * Determines whether a property is defined.
- * A property is defined if there is a getter or setter method
- * defined in the class. Note, property names are case-insensitive.
- * @param string the property name
- * @return boolean whether the property is defined
- */
- public function hasProperty($name)
- {
- return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
- }
-
- /**
- * Determines whether a property can be read.
- * A property can be read if the class has a getter method
- * for the property name. Note, property name is case-insensitive.
- * @param string the property name
- * @return boolean whether the property can be read
- */
- public function canGetProperty($name)
- {
- return method_exists($this,'get'.$name);
- }
-
- /**
- * Determines whether a property can be set.
- * A property can be written if the class has a setter method
- * for the property name. Note, property name is case-insensitive.
- * @param string the property name
- * @return boolean whether the property can be written
- */
- public function canSetProperty($name)
- {
- return method_exists($this,'set'.$name);
- }
-
- /**
- * Evaluates a property path.
- * A property path is a sequence of property names concatenated by '.' character.
- * For example, 'Parent.Page' refers to the 'Page' property of the component's
- * 'Parent' property value (which should be a component also).
- * @param string property path
- * @return mixed the property path value
- */
- public function getSubProperty($path)
- {
- $object=$this;
- foreach(explode('.',$path) as $property)
- $object=$object->$property;
- return $object;
- }
-
- /**
- * Sets a value to a property path.
- * A property path is a sequence of property names concatenated by '.' character.
- * For example, 'Parent.Page' refers to the 'Page' property of the component's
- * 'Parent' property value (which should be a component also).
- * @param string property path
- * @param mixed the property path value
- */
- public function setSubProperty($path,$value)
- {
- $object=$this;
- if(($pos=strrpos($path,'.'))===false)
- $property=$path;
- else
- {
- $object=$this->getSubProperty(substr($path,0,$pos));
- $property=substr($path,$pos+1);
- }
- $object->$property=$value;
- }
-
- /**
- * Determines whether an event is defined.
- * An event is defined if the class has a method whose name is the event name prefixed with 'on'.
- * Note, event name is case-insensitive.
- * @param string the event name
- * @return boolean
- */
- public function hasEvent($name)
- {
- return strncasecmp($name,'on',2)===0 && method_exists($this,$name);
- }
-
- /**
- * @return boolean whether an event has been attached one or several handlers
- */
- public function hasEventHandler($name)
- {
- $name=strtolower($name);
- return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
- }
-
- /**
- * Returns the list of attached event handlers for an event.
- * @return TList list of attached event handlers for an event
- * @throws TInvalidOperationException if the event is not defined
- */
- public function getEventHandlers($name)
- {
- if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
- {
- $name=strtolower($name);
- if(!isset($this->_e[$name]))
- $this->_e[$name]=new TList;
- return $this->_e[$name];
- }
- else
- throw new TInvalidOperationException('component_event_undefined',get_class($this),$name);
- }
-
- /**
- * Attaches an event handler to an event.
- *
- * The handler must be a valid PHP callback, i.e., a string referring to
- * a global function name, or an array containing two elements with
- * the first element being an object and the second element a method name
- * of the object. In Prado, you can also use method path to refer to
- * an event handler. For example, array($object,'Parent.buttonClicked')
- * uses a method path that refers to the method $object->Parent->buttonClicked(...).
- *
- * The event handler must be of the following signature,
- * <code>
- * function handlerName($sender,$param) {}
- * </code>
- * where $sender represents the object that raises the event,
- * and $param is the event parameter.
- *
- * This is a convenient method to add an event handler.
- * It is equivalent to {@link getEventHandlers}($name)->add($handler).
- * For complete management of event handlers, use {@link getEventHandlers}
- * to get the event handler list first, and then do various
- * {@link TList} operations to append, insert or remove
- * event handlers. You may also do these operations like
- * getting and setting properties, e.g.,
- * <code>
- * $component->OnClick[]=array($object,'buttonClicked');
- * $component->OnClick->insertAt(0,array($object,'buttonClicked'));
- * </code>
- * which are equivalent to the following
- * <code>
- * $component->getEventHandlers('OnClick')->add(array($object,'buttonClicked'));
- * $component->getEventHandlers('OnClick')->insertAt(0,array($object,'buttonClicked'));
- * </code>
- *
- * @param string the event name
- * @param callback the event handler
- * @throws TInvalidOperationException if the event does not exist
- */
- public function attachEventHandler($name,$handler)
- {
- $this->getEventHandlers($name)->add($handler);
- }
-
- /**
- * Detaches an existing event handler.
- * This method is the opposite of {@link attachEventHandler}.
- * @param string event name
- * @param callback the event handler to be removed
- * @return boolean if the removal is successful
- */
- public function detachEventHandler($name,$handler)
- {
- if($this->hasEventHandler($name))
- {
- try
- {
- $this->getEventHandlers($name)->remove($handler);
- return true;
- }
- catch(Exception $e)
- {
- }
- }
- return false;
- }
-
- /**
- * Raises an event.
- * This method represents the happening of an event and will
- * invoke all attached event handlers for the event.
- * @param string the event name
- * @param mixed the event sender object
- * @param TEventParameter the event parameter
- * @throws TInvalidOperationException if the event is undefined
- * @throws TInvalidDataValueException If an event handler is invalid
- */
- public function raiseEvent($name,$sender,$param)
- {
- $name=strtolower($name);
- if(isset($this->_e[$name]))
- {
- foreach($this->_e[$name] as $handler)
- {
- if(is_string($handler))
- {
- if(($pos=strrpos($handler,'.'))!==false)
- {
- $object=$this->getSubProperty(substr($handler,0,$pos));
- $method=substr($handler,$pos+1);
- if(method_exists($object,$method))
- $object->$method($sender,$param);
- else
- throw new TInvalidDataValueException('component_eventhandler_invalid',get_class($this),$name);
- }
- else
- call_user_func($handler,$sender,$param);
- }
- else if(is_callable($handler,true))
- {
- // an array: 0 - object, 1 - method name/path
- list($object,$method)=$handler;
- if(is_string($object)) // static method call
- call_user_func($handler,$sender,$param);
- else
- {
- if(($pos=strrpos($method,'.'))!==false)
- {
- $object=$this->getSubProperty(substr($method,0,$pos));
- $method=substr($method,$pos+1);
- }
- if(method_exists($object,$method))
- $object->$method($sender,$param);
- else
- throw new TInvalidDataValueException('component_eventhandler_invalid',get_class($this),$name);
- }
- }
- else
- throw new TInvalidDataValueException('component_eventhandler_invalid',get_class($this),$name);
- }
- }
- else if(!$this->hasEvent($name))
- throw new TInvalidOperationException('component_event_undefined',get_class($this),$name);
- }
-
- /**
- * Evaluates a PHP expression in the context of this control.
- * @return mixed the expression result
- * @throws TInvalidOperationException if the expression is invalid
- */
- public function evaluateExpression($expression)
- {
- try
- {
- if(eval("\$result=$expression;")===false)
- throw new Exception('');
- return $result;
- }
- catch(Exception $e)
- {
- throw new TInvalidOperationException('component_expression_invalid',get_class($this),$expression,$e->getMessage());
- }
- }
-
- /**
- * Evaluates a list of PHP statements.
- * @param string PHP statements
- * @return string content echoed or printed by the PHP statements
- * @throws TInvalidOperationException if the statements are invalid
- */
- public function evaluateStatements($statements)
- {
- try
- {
- ob_start();
- if(eval($statements)===false)
- throw new Exception('');
- $content=ob_get_contents();
- ob_end_clean();
- return $content;
- }
- catch(Exception $e)
- {
- throw new TInvalidOperationException('component_statements_invalid',get_class($this),$statements,$e->getMessage());
- }
- }
-
- /**
- * This method is invoked after the component is instantiated by a template.
- * When this method is invoked, the component's properties have been initialized.
- * The default implementation of this method will invoke
- * the potential parent component's {@link addParsedObject}.
- * This method can be overridden.
- * @param TComponent potential parent of this control
- * @see addParsedObject
- */
- public function createdOnTemplate($parent)
- {
- $parent->addParsedObject($this);
- }
-
- /**
- * Processes an object that is created during parsing template.
- * The object can be either a component or a static text string.
- * This method can be overridden to customize the handling of newly created objects in template.
- * Only framework developers and control developers should use this method.
- * @param string|TComponent text string or component parsed and instantiated in template
- * @see createdOnTemplate
- */
- public function addParsedObject($object)
- {
- }
-}
-
-/**
- * TEnumerable class.
- * TEnumerable is the base class for all enumerable types.
- * To define an enumerable type, extend TEnumberable and define string constants.
- * Each constant represents an enumerable value.
- * The constant name must be the same as the constant value.
- * For example,
- * <code>
- * class TTextAlign extends TEnumerable
- * {
- * const Left='Left';
- * const Right='Right';
- * }
- * </code>
- * Then, one can use the enumerable values such as TTextAlign::Left and
- * TTextAlign::Right.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System
- * @since 3.0
- */
-class TEnumerable
-{
-}
-
-/**
- * TPropertyValue class
- *
- * TPropertyValue is a utility class that provides static methods
- * to convert component property values to specific types.
- *
- * TPropertyValue is commonly used in component setter methods to ensure
- * the new property value is of specific type.
- * For example, a boolean-typed property setter method would be as follows,
- * <code>
- * function setPropertyName($value) {
- * $value=TPropertyValue::ensureBoolean($value);
- * // $value is now of boolean type
- * }
- * </code>
- *
- * Properties can be of the following types with specific type conversion rules:
- * - string: a boolean value will be converted to 'true' or 'false'.
- * - boolean: string 'true' (case-insensitive) will be converted to true,
- * string 'false' (case-insensitive) will be converted to false.
- * - integer
- * - float
- * - array: string starting with '(' and ending with ')' will be considered as
- * as an array expression and will be evaluated. Otherwise, an array
- * with the value to be ensured is returned.
- * - object
- * - enum: enumerable type, represented by an array of strings.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System
- * @since 3.0
- */
-class TPropertyValue
-{
- /**
- * Converts a value to boolean type.
- * Note, string 'true' (case-insensitive) will be converted to true,
- * string 'false' (case-insensitive) will be converted to false.
- * If a string represents a non-zero number, it will be treated as true.
- * @param mixed the value to be converted.
- * @return boolean
- */
- public static function ensureBoolean($value)
- {
- if (is_string($value))
- return strcasecmp($value,'true')==0 || $value!=0;
- else
- return (boolean)$value;
- }
-
- /**
- * Converts a value to string type.
- * Note, a boolean value will be converted to 'true' if it is true
- * and 'false' if it is false.
- * @param mixed the value to be converted.
- * @return string
- */
- public static function ensureString($value)
- {
- if (is_bool($value))
- return $value?'true':'false';
- else
- return (string)$value;
- }
-
- /**
- * Converts a value to integer type.
- * @param mixed the value to be converted.
- * @return integer
- */
- public static function ensureInteger($value)
- {
- return (integer)$value;
- }
-
- /**
- * Converts a value to float type.
- * @param mixed the value to be converted.
- * @return float
- */
- public static function ensureFloat($value)
- {
- return (float)$value;
- }
-
- /**
- * Converts a value to array type. If the value is a string and it is
- * in the form (a,b,c) then an array consisting of each of the elements
- * will be returned. If the value is a string and it is not in this form
- * then an array consisting of just the string will be returned. If the value
- * is not a string then
- * @param mixed the value to be converted.
- * @return array
- */
- public static function ensureArray($value)
- {
- if(is_string($value))
- {
- $trimmed = trim($value);
- $len = strlen($value);
- if ($len >= 2 && $trimmed[0] == '(' && $trimmed[$len-1] == ')')
- {
- eval('$array=array'.$trimmed.';');
- return $array;
- }
- else
- return $len>0?array($value):array();
- }
- else
- return (array)$value;
- }
-
- /**
- * Converts a value to object type.
- * @param mixed the value to be converted.
- * @return object
- */
- public static function ensureObject($value)
- {
- return (object)$value;
- }
-
- /**
- * Converts a value to enum type.
- *
- * This method checks if the value is of the specified enumerable type.
- * A value is a valid enumerable value if it is equal to the name of a constant
- * in the specified enumerable type (class).
- * For more details about enumerable, see {@link TEnumerable}.
- *
- * For backward compatibility, this method also supports sanity
- * check of a string value to see if it is among the given list of strings.
- * @param mixed the value to be converted.
- * @param mixed class name of the enumerable type, or array of valid enumeration values. If this is not an array,
- * the method considers its parameters are of variable length, and the second till the last parameters are enumeration values.
- * @return string the valid enumeration value
- * @throws TInvalidDataValueException if the original value is not in the string array.
- */
- public static function ensureEnum($value,$enums)
- {
- static $types=array();
- if(func_num_args()===2 && is_string($enums))
- {
- if(!isset($types[$enums]))
- $types[$enums]=new ReflectionClass($enums);
- if($types[$enums]->hasConstant($value))
- return $value;
- else
- throw new TInvalidDataValueException(
- 'propertyvalue_enumvalue_invalid',$value,
- implode(' | ',$types[$enums]->getConstants()));
- }
- else if(!is_array($enums))
- {
- $enums=func_get_args();
- array_shift($enums);
- }
- if(in_array($value,$enums,true))
- return $value;
- else
- throw new TInvalidDataValueException('propertyvalue_enumvalue_invalid',$value,implode(' | ',$enums));
- }
-}
-
-/**
- * TEventParameter class.
- * TEventParameter is the base class for all event parameter classes.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System
- * @since 3.0
- */
-class TEventParameter extends TComponent
-{
-}
-
-/**
- * TComponentReflection class.
- *
- * TComponentReflection provides functionalities to inspect the public/protected
- * properties, events and methods defined in a class.
- *
- * The following code displays the properties and events defined in {@link TDataGrid},
- * <code>
- * $reflection=new TComponentReflection('TDataGrid');
- * Prado::varDump($reflection->getProperties());
- * Prado::varDump($reflection->getEvents());
- * </code>
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System
- * @since 3.0
- */
-class TComponentReflection extends TComponent
-{
- private $_className;
- private $_properties=array();
- private $_events=array();
- private $_methods=array();
-
- /**
- * Constructor.
- * @param object|string the component instance or the class name
- * @throws TInvalidDataTypeException if the object is not a component
- */
- public function __construct($component)
- {
- if(is_string($component) && class_exists($component,false))
- $this->_className=$component;
- else if(is_object($component))
- $this->_className=get_class($component);
- else
- throw new TInvalidDataTypeException('componentreflection_class_invalid');
- $this->reflect();
- }
-
- private function isPropertyMethod($method)
- {
- $methodName=$method->getName();
- return $method->getNumberOfRequiredParameters()===0
- && strncasecmp($methodName,'get',3)===0
- && isset($methodName[3]);
- }
-
- private function isEventMethod($method)
- {
- $methodName=$method->getName();
- return strncasecmp($methodName,'on',2)===0
- && isset($methodName[2]);
- }
-
- private function reflect()
- {
- $class=new TReflectionClass($this->_className);
- $properties=array();
- $events=array();
- $methods=array();
- $isComponent=is_subclass_of($this->_className,'TComponent') || strcasecmp($this->_className,'TComponent')===0;
- foreach($class->getMethods() as $method)
- {
- if($method->isPublic() || $method->isProtected())
- {
- $methodName=$method->getName();
- if(!$method->isStatic() && $isComponent)
- {
- if($this->isPropertyMethod($method))
- $properties[substr($methodName,3)]=$method;
- else if($this->isEventMethod($method))
- {
- $methodName[0]='O';
- $events[$methodName]=$method;
- }
- }
- if(strncmp($methodName,'__',2)!==0)
- $methods[$methodName]=$method;
- }
- }
- $reserved=array();
- ksort($properties);
- foreach($properties as $name=>$method)
- {
- $this->_properties[$name]=array(
- 'type'=>$this->determinePropertyType($method),
- 'readonly'=>!$class->hasMethod('set'.$name),
- 'protected'=>$method->isProtected(),
- 'class'=>$method->getDeclaringClass()->getName(),
- 'comments'=>$method->getDocComment()
- );
- $reserved['get'.strtolower($name)]=1;
- $reserved['set'.strtolower($name)]=1;
- }
- ksort($events);
- foreach($events as $name=>$method)
- {
- $this->_events[$name]=array(
- 'class'=>$method->getDeclaringClass()->getName(),
- 'protected'=>$method->isProtected(),
- 'comments'=>$method->getDocComment()
- );
- $reserved[strtolower($name)]=1;
- }
- ksort($methods);
- foreach($methods as $name=>$method)
- {
- if(!isset($reserved[strtolower($name)]))
- $this->_methods[$name]=array(
- 'class'=>$method->getDeclaringClass()->getName(),
- 'protected'=>$method->isProtected(),
- 'static'=>$method->isStatic(),
- 'comments'=>$method->getDocComment()
- );
- }
- }
-
- /**
- * Determines the property type.
- * This method uses the doc comment to determine the property type.
- * @param ReflectionMethod
- * @return string the property type, '{unknown}' if type cannot be determined from comment
- */
- protected function determinePropertyType($method)
- {
- $comment=$method->getDocComment();
- if(preg_match('/@return\\s+(.*?)\\s+/',$comment,$matches))
- return $matches[1];
- else
- return '{unknown}';
- }
-
- /**
- * @return string class name of the component
- */
- public function getClassName()
- {
- return $this->_className;
- }
-
- /**
- * @return array list of component properties. Array keys are property names.
- * Each array element is of the following structure:
- * [type]=>property type,
- * [readonly]=>whether the property is read-only,
- * [protected]=>whether the method is protected or not
- * [class]=>the class where the property is inherited from,
- * [comments]=>comments associated with the property.
- */
- public function getProperties()
- {
- return $this->_properties;
- }
-
- /**
- * @return array list of component events. Array keys are event names.
- * Each array element is of the following structure:
- * [protected]=>whether the event is protected or not
- * [class]=>the class where the event is inherited from.
- * [comments]=>comments associated with the event.
- */
- public function getEvents()
- {
- return $this->_events;
- }
-
- /**
- * @return array list of public/protected methods. Array keys are method names.
- * Each array element is of the following structure:
- * [protected]=>whether the method is protected or not
- * [static]=>whether the method is static or not
- * [class]=>the class where the property is inherited from,
- * [comments]=>comments associated with the event.
- */
- public function getMethods()
- {
- return $this->_methods;
- }
-}
-
+<?php
+/**
+ * TComponent, TPropertyValue classes
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System
+ */
+
+/**
+ * TComponent class
+ *
+ * TComponent is the base class for all PRADO components.
+ * TComponent implements the protocol of defining, using properties and events.
+ *
+ * A property is defined by a getter method, and/or a setter method.
+ * Properties can be accessed in the way like accessing normal object members.
+ * Reading or writing a property will cause the invocation of the corresponding
+ * getter or setter method, e.g.,
+ * <code>
+ * $a=$this->Text; // equivalent to $a=$this->getText();
+ * $this->Text='abc'; // equivalent to $this->setText('abc');
+ * </code>
+ * The signatures of getter and setter methods are as follows,
+ * <code>
+ * // getter, defines a readable property 'Text'
+ * function getText() { ... }
+ * // setter, defines a writable property 'Text', with $value being the value to be set to the property
+ * function setText($value) { ... }
+ * </code>
+ * Property names are case-insensitive. It is recommended that they are written
+ * in the format of concatenated words, with the first letter of each word
+ * capitalized (e.g. DisplayMode, ItemStyle).
+ *
+ * An event is defined by the presence of a method whose name starts with 'on'.
+ * The event name is the method name and is thus case-insensitive.
+ * An event can be attached with one or several methods (called event handlers).
+ * An event can be raised by calling {@link raiseEvent} method, upon which
+ * the attached event handlers will be invoked automatically in the order they
+ * are attached to the event. Event handlers must have the following signature,
+ * <code>
+ * function eventHandlerFuncName($sender,$param) { ... }
+ * </code>
+ * where $sender refers to the object who is responsible for the raising of the event,
+ * and $param refers to a structure that may contain event-specific information.
+ * To raise an event (assuming named as 'Click') of a component, use
+ * <code>
+ * $component->raiseEvent('OnClick');
+ * </code>
+ * To attach an event handler to an event, use one of the following ways,
+ * <code>
+ * $component->OnClick=$callback; // or $component->OnClick->add($callback);
+ * $$component->attachEventHandler('OnClick',$callback);
+ * </code>
+ * The first two ways make use of the fact that $component->OnClick refers to
+ * the event handler list {@link TList} for the 'OnClick' event.
+ * The variable $callback contains the definition of the event handler that can
+ * be either a string referring to a global function name, or an array whose
+ * first element refers to an object and second element a method name/path that
+ * is reachable by the object, e.g.
+ * - 'buttonClicked' : buttonClicked($sender,$param);
+ * - array($object,'buttonClicked') : $object->buttonClicked($sender,$param);
+ * - array($object,'MainContent.SubmitButton.buttonClicked') :
+ * $object->MainContent->SubmitButton->buttonClicked($sender,$param);
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System
+ * @since 3.0
+ */
+class TComponent
+{
+ /**
+ * @var array event handler lists
+ */
+ private $_e=array();
+
+ /**
+ * Returns a property value or an event handler list by property or event name.
+ * Do not call this method. This is a PHP magic method that we override
+ * to allow using the following syntax to read a property:
+ * <code>
+ * $value=$component->PropertyName;
+ * </code>
+ * and to obtain the event handler list for an event,
+ * <code>
+ * $eventHandlerList=$component->EventName;
+ * </code>
+ * @param string the property name or the event name
+ * @return mixed the property value or the event handler list
+ * @throws TInvalidOperationException if the property/event is not defined.
+ */
+ public function __get($name)
+ {
+ $getter='get'.$name;
+ if(method_exists($this,$getter))
+ {
+ // getting a property
+ return $this->$getter();
+ }
+ else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
+ {
+ // getting an event (handler list)
+ $name=strtolower($name);
+ if(!isset($this->_e[$name]))
+ $this->_e[$name]=new TList;
+ return $this->_e[$name];
+ }
+ else
+ {
+ throw new TInvalidOperationException('component_property_undefined',get_class($this),$name);
+ }
+ }
+
+ /**
+ * Sets value of a component property.
+ * Do not call this method. This is a PHP magic method that we override
+ * to allow using the following syntax to set a property or attach an event handler.
+ * <code>
+ * $this->PropertyName=$value;
+ * $this->EventName=$handler;
+ * </code>
+ * @param string the property name or event name
+ * @param mixed the property value or event handler
+ * @throws TInvalidOperationException If the property is not defined or read-only.
+ */
+ public function __set($name,$value)
+ {
+ $setter='set'.$name;
+ if(method_exists($this,$setter))
+ {
+ $this->$setter($value);
+ }
+ else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
+ {
+ $this->attachEventHandler($name,$value);
+ }
+ else if(method_exists($this,'get'.$name))
+ {
+ throw new TInvalidOperationException('component_property_readonly',get_class($this),$name);
+ }
+ else
+ {
+ throw new TInvalidOperationException('component_property_undefined',get_class($this),$name);
+ }
+ }
+
+ /**
+ * Determines whether a property is defined.
+ * A property is defined if there is a getter or setter method
+ * defined in the class. Note, property names are case-insensitive.
+ * @param string the property name
+ * @return boolean whether the property is defined
+ */
+ public function hasProperty($name)
+ {
+ return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
+ }
+
+ /**
+ * Determines whether a property can be read.
+ * A property can be read if the class has a getter method
+ * for the property name. Note, property name is case-insensitive.
+ * @param string the property name
+ * @return boolean whether the property can be read
+ */
+ public function canGetProperty($name)
+ {
+ return method_exists($this,'get'.$name);
+ }
+
+ /**
+ * Determines whether a property can be set.
+ * A property can be written if the class has a setter method
+ * for the property name. Note, property name is case-insensitive.
+ * @param string the property name
+ * @return boolean whether the property can be written
+ */
+ public function canSetProperty($name)
+ {
+ return method_exists($this,'set'.$name);
+ }
+
+ /**
+ * Evaluates a property path.
+ * A property path is a sequence of property names concatenated by '.' character.
+ * For example, 'Parent.Page' refers to the 'Page' property of the component's
+ * 'Parent' property value (which should be a component also).
+ * @param string property path
+ * @return mixed the property path value
+ */
+ public function getSubProperty($path)
+ {
+ $object=$this;
+ foreach(explode('.',$path) as $property)
+ $object=$object->$property;
+ return $object;
+ }
+
+ /**
+ * Sets a value to a property path.
+ * A property path is a sequence of property names concatenated by '.' character.
+ * For example, 'Parent.Page' refers to the 'Page' property of the component's
+ * 'Parent' property value (which should be a component also).
+ * @param string property path
+ * @param mixed the property path value
+ */
+ public function setSubProperty($path,$value)
+ {
+ $object=$this;
+ if(($pos=strrpos($path,'.'))===false)
+ $property=$path;
+ else
+ {
+ $object=$this->getSubProperty(substr($path,0,$pos));
+ $property=substr($path,$pos+1);
+ }
+ $object->$property=$value;
+ }
+
+ /**
+ * Determines whether an event is defined.
+ * An event is defined if the class has a method whose name is the event name prefixed with 'on'.
+ * Note, event name is case-insensitive.
+ * @param string the event name
+ * @return boolean
+ */
+ public function hasEvent($name)
+ {
+ return strncasecmp($name,'on',2)===0 && method_exists($this,$name);
+ }
+
+ /**
+ * @return boolean whether an event has been attached one or several handlers
+ */
+ public function hasEventHandler($name)
+ {
+ $name=strtolower($name);
+ return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
+ }
+
+ /**
+ * Returns the list of attached event handlers for an event.
+ * @return TList list of attached event handlers for an event
+ * @throws TInvalidOperationException if the event is not defined
+ */
+ public function getEventHandlers($name)
+ {
+ if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
+ {
+ $name=strtolower($name);
+ if(!isset($this->_e[$name]))
+ $this->_e[$name]=new TList;
+ return $this->_e[$name];
+ }
+ else
+ throw new TInvalidOperationException('component_event_undefined',get_class($this),$name);
+ }
+
+ /**
+ * Attaches an event handler to an event.
+ *
+ * The handler must be a valid PHP callback, i.e., a string referring to
+ * a global function name, or an array containing two elements with
+ * the first element being an object and the second element a method name
+ * of the object. In Prado, you can also use method path to refer to
+ * an event handler. For example, array($object,'Parent.buttonClicked')
+ * uses a method path that refers to the method $object->Parent->buttonClicked(...).
+ *
+ * The event handler must be of the following signature,
+ * <code>
+ * function handlerName($sender,$param) {}
+ * </code>
+ * where $sender represents the object that raises the event,
+ * and $param is the event parameter.
+ *
+ * This is a convenient method to add an event handler.
+ * It is equivalent to {@link getEventHandlers}($name)->add($handler).
+ * For complete management of event handlers, use {@link getEventHandlers}
+ * to get the event handler list first, and then do various
+ * {@link TList} operations to append, insert or remove
+ * event handlers. You may also do these operations like
+ * getting and setting properties, e.g.,
+ * <code>
+ * $component->OnClick[]=array($object,'buttonClicked');
+ * $component->OnClick->insertAt(0,array($object,'buttonClicked'));
+ * </code>
+ * which are equivalent to the following
+ * <code>
+ * $component->getEventHandlers('OnClick')->add(array($object,'buttonClicked'));
+ * $component->getEventHandlers('OnClick')->insertAt(0,array($object,'buttonClicked'));
+ * </code>
+ *
+ * @param string the event name
+ * @param callback the event handler
+ * @throws TInvalidOperationException if the event does not exist
+ */
+ public function attachEventHandler($name,$handler)
+ {
+ $this->getEventHandlers($name)->add($handler);
+ }
+
+ /**
+ * Detaches an existing event handler.
+ * This method is the opposite of {@link attachEventHandler}.
+ * @param string event name
+ * @param callback the event handler to be removed
+ * @return boolean if the removal is successful
+ */
+ public function detachEventHandler($name,$handler)
+ {
+ if($this->hasEventHandler($name))
+ {
+ try
+ {
+ $this->getEventHandlers($name)->remove($handler);
+ return true;
+ }
+ catch(Exception $e)
+ {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Raises an event.
+ * This method represents the happening of an event and will
+ * invoke all attached event handlers for the event.
+ * @param string the event name
+ * @param mixed the event sender object
+ * @param TEventParameter the event parameter
+ * @throws TInvalidOperationException if the event is undefined
+ * @throws TInvalidDataValueException If an event handler is invalid
+ */
+ public function raiseEvent($name,$sender,$param)
+ {
+ $name=strtolower($name);
+ if(isset($this->_e[$name]))
+ {
+ foreach($this->_e[$name] as $handler)
+ {
+ if(is_string($handler))
+ {
+ if(($pos=strrpos($handler,'.'))!==false)
+ {
+ $object=$this->getSubProperty(substr($handler,0,$pos));
+ $method=substr($handler,$pos+1);
+ if(method_exists($object,$method))
+ $object->$method($sender,$param);
+ else
+ throw new TInvalidDataValueException('component_eventhandler_invalid',get_class($this),$name,get_class($object).'::'.$method.'()');
+ }
+ else
+ call_user_func($handler,$sender,$param);
+ }
+ else if(is_callable($handler,true))
+ {
+ // an array: 0 - object, 1 - method name/path
+ list($object,$method)=$handler;
+ if(is_string($object)) // static method call
+ call_user_func($handler,$sender,$param);
+ else
+ {
+ if(($pos=strrpos($method,'.'))!==false)
+ {
+ $object=$this->getSubProperty(substr($method,0,$pos));
+ $method=substr($method,$pos+1);
+ }
+ if(method_exists($object,$method))
+ $object->$method($sender,$param);
+ else
+ throw new TInvalidDataValueException('component_eventhandler_invalid',get_class($this),$name,get_class($object).'::'.$method.'()');
+ }
+ }
+ else
+ throw new TInvalidDataValueException('component_eventhandler_invalid',get_class($this),$name,get_class($object).'::'.$method.'()');
+ }
+ }
+ else if(!$this->hasEvent($name))
+ throw new TInvalidOperationException('component_event_undefined',get_class($this),$name);
+ }
+
+ /**
+ * Evaluates a PHP expression in the context of this control.
+ * @return mixed the expression result
+ * @throws TInvalidOperationException if the expression is invalid
+ */
+ public function evaluateExpression($expression)
+ {
+ try
+ {
+ if(eval("\$result=$expression;")===false)
+ throw new Exception('');
+ return $result;
+ }
+ catch(Exception $e)
+ {
+ throw new TInvalidOperationException('component_expression_invalid',get_class($this),$expression,$e->getMessage());
+ }
+ }
+
+ /**
+ * Evaluates a list of PHP statements.
+ * @param string PHP statements
+ * @return string content echoed or printed by the PHP statements
+ * @throws TInvalidOperationException if the statements are invalid
+ */
+ public function evaluateStatements($statements)
+ {
+ try
+ {
+ ob_start();
+ if(eval($statements)===false)
+ throw new Exception('');
+ $content=ob_get_contents();
+ ob_end_clean();
+ return $content;
+ }
+ catch(Exception $e)
+ {
+ throw new TInvalidOperationException('component_statements_invalid',get_class($this),$statements,$e->getMessage());
+ }
+ }
+
+ /**
+ * This method is invoked after the component is instantiated by a template.
+ * When this method is invoked, the component's properties have been initialized.
+ * The default implementation of this method will invoke
+ * the potential parent component's {@link addParsedObject}.
+ * This method can be overridden.
+ * @param TComponent potential parent of this control
+ * @see addParsedObject
+ */
+ public function createdOnTemplate($parent)
+ {
+ $parent->addParsedObject($this);
+ }
+
+ /**
+ * Processes an object that is created during parsing template.
+ * The object can be either a component or a static text string.
+ * This method can be overridden to customize the handling of newly created objects in template.
+ * Only framework developers and control developers should use this method.
+ * @param string|TComponent text string or component parsed and instantiated in template
+ * @see createdOnTemplate
+ */
+ public function addParsedObject($object)
+ {
+ }
+}
+
+/**
+ * TEnumerable class.
+ * TEnumerable is the base class for all enumerable types.
+ * To define an enumerable type, extend TEnumberable and define string constants.
+ * Each constant represents an enumerable value.
+ * The constant name must be the same as the constant value.
+ * For example,
+ * <code>
+ * class TTextAlign extends TEnumerable
+ * {
+ * const Left='Left';
+ * const Right='Right';
+ * }
+ * </code>
+ * Then, one can use the enumerable values such as TTextAlign::Left and
+ * TTextAlign::Right.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System
+ * @since 3.0
+ */
+class TEnumerable
+{
+}
+
+/**
+ * TPropertyValue class
+ *
+ * TPropertyValue is a utility class that provides static methods
+ * to convert component property values to specific types.
+ *
+ * TPropertyValue is commonly used in component setter methods to ensure
+ * the new property value is of specific type.
+ * For example, a boolean-typed property setter method would be as follows,
+ * <code>
+ * function setPropertyName($value) {
+ * $value=TPropertyValue::ensureBoolean($value);
+ * // $value is now of boolean type
+ * }
+ * </code>
+ *
+ * Properties can be of the following types with specific type conversion rules:
+ * - string: a boolean value will be converted to 'true' or 'false'.
+ * - boolean: string 'true' (case-insensitive) will be converted to true,
+ * string 'false' (case-insensitive) will be converted to false.
+ * - integer
+ * - float
+ * - array: string starting with '(' and ending with ')' will be considered as
+ * as an array expression and will be evaluated. Otherwise, an array
+ * with the value to be ensured is returned.
+ * - object
+ * - enum: enumerable type, represented by an array of strings.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System
+ * @since 3.0
+ */
+class TPropertyValue
+{
+ /**
+ * Converts a value to boolean type.
+ * Note, string 'true' (case-insensitive) will be converted to true,
+ * string 'false' (case-insensitive) will be converted to false.
+ * If a string represents a non-zero number, it will be treated as true.
+ * @param mixed the value to be converted.
+ * @return boolean
+ */
+ public static function ensureBoolean($value)
+ {
+ if (is_string($value))
+ return strcasecmp($value,'true')==0 || $value!=0;
+ else
+ return (boolean)$value;
+ }
+
+ /**
+ * Converts a value to string type.
+ * Note, a boolean value will be converted to 'true' if it is true
+ * and 'false' if it is false.
+ * @param mixed the value to be converted.
+ * @return string
+ */
+ public static function ensureString($value)
+ {
+ if (is_bool($value))
+ return $value?'true':'false';
+ else
+ return (string)$value;
+ }
+
+ /**
+ * Converts a value to integer type.
+ * @param mixed the value to be converted.
+ * @return integer
+ */
+ public static function ensureInteger($value)
+ {
+ return (integer)$value;
+ }
+
+ /**
+ * Converts a value to float type.
+ * @param mixed the value to be converted.
+ * @return float
+ */
+ public static function ensureFloat($value)
+ {
+ return (float)$value;
+ }
+
+ /**
+ * Converts a value to array type. If the value is a string and it is
+ * in the form (a,b,c) then an array consisting of each of the elements
+ * will be returned. If the value is a string and it is not in this form
+ * then an array consisting of just the string will be returned. If the value
+ * is not a string then
+ * @param mixed the value to be converted.
+ * @return array
+ */
+ public static function ensureArray($value)
+ {
+ if(is_string($value))
+ {
+ $trimmed = trim($value);
+ $len = strlen($value);
+ if ($len >= 2 && $trimmed[0] == '(' && $trimmed[$len-1] == ')')
+ {
+ eval('$array=array'.$trimmed.';');
+ return $array;
+ }
+ else
+ return $len>0?array($value):array();
+ }
+ else
+ return (array)$value;
+ }
+
+ /**
+ * Converts a value to object type.
+ * @param mixed the value to be converted.
+ * @return object
+ */
+ public static function ensureObject($value)
+ {
+ return (object)$value;
+ }
+
+ /**
+ * Converts a value to enum type.
+ *
+ * This method checks if the value is of the specified enumerable type.
+ * A value is a valid enumerable value if it is equal to the name of a constant
+ * in the specified enumerable type (class).
+ * For more details about enumerable, see {@link TEnumerable}.
+ *
+ * For backward compatibility, this method also supports sanity
+ * check of a string value to see if it is among the given list of strings.
+ * @param mixed the value to be converted.
+ * @param mixed class name of the enumerable type, or array of valid enumeration values. If this is not an array,
+ * the method considers its parameters are of variable length, and the second till the last parameters are enumeration values.
+ * @return string the valid enumeration value
+ * @throws TInvalidDataValueException if the original value is not in the string array.
+ */
+ public static function ensureEnum($value,$enums)
+ {
+ static $types=array();
+ if(func_num_args()===2 && is_string($enums))
+ {
+ if(!isset($types[$enums]))
+ $types[$enums]=new ReflectionClass($enums);
+ if($types[$enums]->hasConstant($value))
+ return $value;
+ else
+ throw new TInvalidDataValueException(
+ 'propertyvalue_enumvalue_invalid',$value,
+ implode(' | ',$types[$enums]->getConstants()));
+ }
+ else if(!is_array($enums))
+ {
+ $enums=func_get_args();
+ array_shift($enums);
+ }
+ if(in_array($value,$enums,true))
+ return $value;
+ else
+ throw new TInvalidDataValueException('propertyvalue_enumvalue_invalid',$value,implode(' | ',$enums));
+ }
+}
+
+/**
+ * TEventParameter class.
+ * TEventParameter is the base class for all event parameter classes.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System
+ * @since 3.0
+ */
+class TEventParameter extends TComponent
+{
+}
+
+/**
+ * TComponentReflection class.
+ *
+ * TComponentReflection provides functionalities to inspect the public/protected
+ * properties, events and methods defined in a class.
+ *
+ * The following code displays the properties and events defined in {@link TDataGrid},
+ * <code>
+ * $reflection=new TComponentReflection('TDataGrid');
+ * Prado::varDump($reflection->getProperties());
+ * Prado::varDump($reflection->getEvents());
+ * </code>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System
+ * @since 3.0
+ */
+class TComponentReflection extends TComponent
+{
+ private $_className;
+ private $_properties=array();
+ private $_events=array();
+ private $_methods=array();
+
+ /**
+ * Constructor.
+ * @param object|string the component instance or the class name
+ * @throws TInvalidDataTypeException if the object is not a component
+ */
+ public function __construct($component)
+ {
+ if(is_string($component) && class_exists($component,false))
+ $this->_className=$component;
+ else if(is_object($component))
+ $this->_className=get_class($component);
+ else
+ throw new TInvalidDataTypeException('componentreflection_class_invalid');
+ $this->reflect();
+ }
+
+ private function isPropertyMethod($method)
+ {
+ $methodName=$method->getName();
+ return $method->getNumberOfRequiredParameters()===0
+ && strncasecmp($methodName,'get',3)===0
+ && isset($methodName[3]);
+ }
+
+ private function isEventMethod($method)
+ {
+ $methodName=$method->getName();
+ return strncasecmp($methodName,'on',2)===0
+ && isset($methodName[2]);
+ }
+
+ private function reflect()
+ {
+ $class=new TReflectionClass($this->_className);
+ $properties=array();
+ $events=array();
+ $methods=array();
+ $isComponent=is_subclass_of($this->_className,'TComponent') || strcasecmp($this->_className,'TComponent')===0;
+ foreach($class->getMethods() as $method)
+ {
+ if($method->isPublic() || $method->isProtected())
+ {
+ $methodName=$method->getName();
+ if(!$method->isStatic() && $isComponent)
+ {
+ if($this->isPropertyMethod($method))
+ $properties[substr($methodName,3)]=$method;
+ else if($this->isEventMethod($method))
+ {
+ $methodName[0]='O';
+ $events[$methodName]=$method;
+ }
+ }
+ if(strncmp($methodName,'__',2)!==0)
+ $methods[$methodName]=$method;
+ }
+ }
+ $reserved=array();
+ ksort($properties);
+ foreach($properties as $name=>$method)
+ {
+ $this->_properties[$name]=array(
+ 'type'=>$this->determinePropertyType($method),
+ 'readonly'=>!$class->hasMethod('set'.$name),
+ 'protected'=>$method->isProtected(),
+ 'class'=>$method->getDeclaringClass()->getName(),
+ 'comments'=>$method->getDocComment()
+ );
+ $reserved['get'.strtolower($name)]=1;
+ $reserved['set'.strtolower($name)]=1;
+ }
+ ksort($events);
+ foreach($events as $name=>$method)
+ {
+ $this->_events[$name]=array(
+ 'class'=>$method->getDeclaringClass()->getName(),
+ 'protected'=>$method->isProtected(),
+ 'comments'=>$method->getDocComment()
+ );
+ $reserved[strtolower($name)]=1;
+ }
+ ksort($methods);
+ foreach($methods as $name=>$method)
+ {
+ if(!isset($reserved[strtolower($name)]))
+ $this->_methods[$name]=array(
+ 'class'=>$method->getDeclaringClass()->getName(),
+ 'protected'=>$method->isProtected(),
+ 'static'=>$method->isStatic(),
+ 'comments'=>$method->getDocComment()
+ );
+ }
+ }
+
+ /**
+ * Determines the property type.
+ * This method uses the doc comment to determine the property type.
+ * @param ReflectionMethod
+ * @return string the property type, '{unknown}' if type cannot be determined from comment
+ */
+ protected function determinePropertyType($method)
+ {
+ $comment=$method->getDocComment();
+ if(preg_match('/@return\\s+(.*?)\\s+/',$comment,$matches))
+ return $matches[1];
+ else
+ return '{unknown}';
+ }
+
+ /**
+ * @return string class name of the component
+ */
+ public function getClassName()
+ {
+ return $this->_className;
+ }
+
+ /**
+ * @return array list of component properties. Array keys are property names.
+ * Each array element is of the following structure:
+ * [type]=>property type,
+ * [readonly]=>whether the property is read-only,
+ * [protected]=>whether the method is protected or not
+ * [class]=>the class where the property is inherited from,
+ * [comments]=>comments associated with the property.
+ */
+ public function getProperties()
+ {
+ return $this->_properties;
+ }
+
+ /**
+ * @return array list of component events. Array keys are event names.
+ * Each array element is of the following structure:
+ * [protected]=>whether the event is protected or not
+ * [class]=>the class where the event is inherited from.
+ * [comments]=>comments associated with the event.
+ */
+ public function getEvents()
+ {
+ return $this->_events;
+ }
+
+ /**
+ * @return array list of public/protected methods. Array keys are method names.
+ * Each array element is of the following structure:
+ * [protected]=>whether the method is protected or not
+ * [static]=>whether the method is static or not
+ * [class]=>the class where the property is inherited from,
+ * [comments]=>comments associated with the event.
+ */
+ public function getMethods()
+ {
+ return $this->_methods;
+ }
+}
+
?> \ No newline at end of file