Zend Framework: Translateable Exceptions for ZF Component Proposal
| Proposed Component Name | Translateable Exceptions for ZF |
|---|---|
| Developer Notes | http://framework.zend.com/wiki/display/ZFDEV/Translateable Exceptions for ZF |
| Proposers | Thomas Weidner |
| Zend Liaison | Wil Sinclair |
| Revision | 1.0 - 17 January 2009: Initial Draft 1.1 - 17 January 2009: getTranslatedMessage() -> getLocalizedMessage() (wiki revision: 9) |
Table of Contents
1. Overview
Translateable Exceptions is not a component but a feature addition to the existing generic Zend_Exception class.
It allows to add behaviour to translate exceptions from ZF into any other language.
2. References
None
3. Component Requirements, Constraints, and Acceptance Criteria
- This feature will extend Zend_Exception
- This feature will not add translations themself for the components
- This feature will not need users to change anything on their existing code
4. Dependencies on Other Framework Components
- Zend_Exception
- Zend_Locale
- Zend_Translate
5. Theory of Operation
This feature adds the possibility to translate any thrown exception into a previous given language.
Therefor some changes are needed which can be done component based. Also not all changes are needed by all components.
- First:
Providing translations for component-exceptions on a generic directory.
We will therefor use the existing translation teams.
The directory where the translations from ZF are stored will be:
library/Zend/Exception/Translation/en
For each available language a new directory (locale) can be added.
Each component adds it's own translation file. So we have a Zend_Currency.xxx
As format I would propose to use array. It's the fastest adapter as it only ready and does no parsing.
- Second:
When variables are used in the exception message the exception class has give these values explicit as parameter at contruction.
Otherwise we would not be able to translate and provide the values.
- Third:
Add a static property to be able to activate translated exceptions.
As the original proposal for changing the exception behaviour was not accepted we have no exception code nor do we have translation constants to know which exception was thrown.
Therefor we need to provide the complete message as key value which adds additionally performance overhead. It also adds the problem that one single false character leads to a non-translated exception message.
Or when the original exception was changed it could also no longer be translated.
- Forth:
It will detect application wide locale. But translation will only be done when the static property is set.
- Sixth:
I additionally propose that we also add exception codes for translated exceptions. This would:- simplify translation
- add codes for those who need, even if most do not. Actually many people ask for it and seem to use this feature
- allow to add help based on exception codes in wiki when requested
- also allow to provide a list of exceptions with their code in the manual as this is the same work for the translators when they translate the exceptions themself
Background of this proposal
Exceptions are, normally, not displayed to users.
But this proposal allows two great features to be used which are useful for non-native english speakers.
Exception messages are normally logged. With this proposal you are able also to provide a localized log file even when exceptions are added to the log.
Sometimes it is necessary to rewrite the returned exception message.
When, for example, the exception message would say "database table xxx not found"... for security reasons you would like to rewrite the message to "Db problems, please ask your database admin".
With this proposal those two features are possible.
6. Milestones / Tasks
- Milestone 1: [done] Proposal written
- Milestone 2: Proposal accepted
- Milestone 3: Prototype
- Milestone 4: Unittests
- Milestone 5: Documentation
- Milestone 6: Add ability for each available component
- Milestone 7: Translate messages
7. Class Index
- Zend_Exception
8. Use Cases
| UC-01 |
|---|
Default usage for translation, detects application locale
| UC-02 |
|---|
Manual usage of translating exceptions
| UC-03 |
|---|
Manual usage of translating exceptions by giving a fixed locale
9. Class Skeletons
No change in the Exception class of the component
A thrown exception
There are some use cases where the message I'd show to a user isn't the same that I'd show to a developer/administrator/internal* (or write in a log file). Would it be possible to set two different messages, one for the user that can be translated and one with all the details? Of course by default they would be the same.
You could archive this by adding a new language which the user can not select (for example de_US).
Add the admin translations to this language.
Display the user only his language and when you log the message, use the locale de_US for translation.
This solutions does even work with the actual translation by using log for example (without exceptions).
Since PHP 5.3.0 the third parameter for Exception::__construct is a previous exception but in your last example you use the third param as a values array
-> http://php.net/manual/en/exception.construct.php
A thrown exception
new Zend_Component_Exception("My exception with value %1/$s and %2/$s", 4033, array($value1, $value2));
This proposal was written at a time where PHP 5.3 was not available.
Still this would not be a problem. It is simple to detect if a exception class was given as third parameter or only a array. And as PHP 5.2.4, which is the minimum requirement for ZF, does not support a third parameter for exception objects we would in any case have to support both ways.
And in ZF 2.0 we would have to change this completly? We must think about this anyway... Why not implement it in a "future save way" right from the beginning?
I don't understand your problems...
I said "we have to support both ways". I did not say that this will change in ZF 2.0 as this would be nonsense. We want to support all php versions above 5.2.4 for new components.
The example just shows the usage within php 5.2.4 which is the minimum required version for ZF.
I have added this Exception issue as a new Proposal:
-> http://framework.zend.com/wiki/display/ZFPROP/previous+Exception+on+Zend_Exception+-+Marc+Bennewitz
As sidenote:
I still have the opinion that exceptions within the complete framework should provide exception codes. This could be used to decide which exceptions should be translated and which not. f.e. Auth has numbers from 1000-1999, so we could limit translations to just this range.
This would be very nice.
The components exceptions codes could be simply selected by a mask defined by a constant of the current component like the following:
the base Zend Exception codes are between 0x000000 and 0x00FFFF:
-> Zend_Exception::EXCEPTION_CODE_MASK = 0x00FFFF;
All components have a range:
-> Zend_[Component]::EXCEPTION_CODE_MASK = 0x01FFFF;
All Subcomponents have a subrange:
-> Zend_[Component]_[Subcomponent]::EXCEPTIONS_CODE_MASK = 0x0101FF;
ZF Home Page
Code Browser
Wiki Dashboard
How about renaming the method getTranslatedMessage() to getLocalizedMessage(), to indicate that the message may also contain other localized elements (numbers, dates, etc) in addition to the localized/translated message.
This is also what it's called in Java, so it will be recognized by people coming from the Java world.