Kaynağa Gözat

[ZF-6816, ZF-6817] Zend_Currency:

- new Zend_Currency implementation
- added currency calculation (ZF-6817)
- added exchange interface (ZF-6816)
- added new manual

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@20100 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 yıl önce
ebeveyn
işleme
0a3155a7e9

+ 42 - 2
documentation/manual/en/manual.xml.in

@@ -4,7 +4,7 @@
 [
     <!ENTITY % xinclude SYSTEM "../en/xinclude.mod">
     %xinclude;
-    
+
     <!-- Add translated specific definitions and snippets -->
     <!ENTITY % language-snippets SYSTEM "./ref/language-snippets.xml">
     %language-snippets;
@@ -274,7 +274,7 @@
                 </xi:fallback>
             </xi:include>
         </chapter>
-        
+
         <chapter id="learning.paginator">
             <title>&part.learning.paginator.title;</title>
             <xi:include href="tutorials/paginator-intro.xml">
@@ -628,6 +628,46 @@
                     <xi:include href="../en/module_specs/Zend_Currency-Usage.xml" />
                 </xi:fallback>
             </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Options.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Options.xml" />
+                </xi:fallback>
+            </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Description.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Description.xml" />
+                </xi:fallback>
+            </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Position.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Position.xml" />
+                </xi:fallback>
+            </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Number.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Number.xml" />
+                </xi:fallback>
+            </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Value.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Value.xml" />
+                </xi:fallback>
+            </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Calculation.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Calculation.xml" />
+                </xi:fallback>
+            </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Exchange.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Exchange.xml" />
+                </xi:fallback>
+            </xi:include>
+            <xi:include href="module_specs/Zend_Currency-Additional.xml">
+                <xi:fallback>
+                    <xi:include href="../en/module_specs/Zend_Currency-Additional.xml" />
+                </xi:fallback>
+            </xi:include>
         </chapter>
 
         <chapter id="zend.date">

+ 136 - 0
documentation/manual/en/module_specs/Zend_Currency-Additional.xml

@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.additional">
+    <title>Additional informations on Zend_Currency</title>
+
+    <sect2 id="zend.currency.additional.informations">
+        <title>Currency informations</title>
+
+        <para>
+            Sometimes it is necessary to get informations which are related to a currency.
+            <classname>Zend_Currency</classname> provides you with several methods to get this
+            informations. Available methods include the following:
+        </para>
+
+        <itemizedlist mark='opencircle'>
+            <listitem>
+                <para>
+                    <emphasis><methodname>getCurrencyList()</methodname></emphasis>: Returns a list
+                    of all currencies which are used in the given region as array. Defaults to the
+                    objects locale when no region has been given.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis><methodname>getLocale()</methodname></emphasis>: Returns the set
+                    locale for the actual currency.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis><methodname>getName()</methodname></emphasis>: Returns the full name
+                    for the actual currency. When there is no full name available for the actual
+                    currency, it will return the abbreviation for it.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis><methodname>getRegionList()</methodname></emphasis>: Returns a list
+                    of all regions where this currency is used as array. Defaults to the objects
+                    currency when no currency has been given.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis><methodname>getService()</methodname></emphasis>: Returns the set
+                    exchange service object for the actual currency.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis><methodname>getShortName()</methodname></emphasis>: Returns the
+                    abbreviation for the actual currency.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis><methodname>getSymbol()</methodname></emphasis>: Returns the currency
+                    sign for the currency. When the currency has no symbol, then it will return the
+                    abbreviation for it.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis><methodname>getValue()</methodname></emphasis>: Returns the set
+                    value for the actual currency.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Let's see some code snippets as example:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency();
+
+var_dump($currency->getValue());
+// returns 0
+
+var_dump($currency->getRegionList());
+// could return an array with all regions where USD is used
+
+var_dump($currency->getRegionList('EUR'));
+// returns an array with all regions where EUR is used
+
+var_dump($currency->getName());
+// could return 'US Dollar'
+
+var_dump($currency->getName('EUR'));
+// returns 'Euro'
+]]></programlisting>
+
+        <para>
+            As you can see, several methods allow to use additional parameters to override the
+            actual object to get informations for other currencies. Omitting this parameters will
+            return informations from the actual set currency.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.currency.additional.cache">
+        <title>Currency Performance Optimization</title>
+
+        <para>
+            <classname>Zend_Currency</classname>'s performance can be optimized using
+            <classname>Zend_Cache</classname>. The static method
+            <methodname>Zend_Currency::setCache($cache)</methodname> accepts one option: a
+            <classname>Zend_Cache</classname> adapter. If the cache adapter is set, the localization
+            data which is used by <classname>Zend_Currency</classname> will be cached. Additionally
+            there are some static methods for manipulating the cache:
+            <methodname>getCache()</methodname>, <methodname>hasCache()</methodname>,
+            <methodname>clearCache()</methodname> and <methodname>removeCache()</methodname>.
+        </para>
+
+        <example id="zend.currency.usage.cache.example">
+            <title>Caching currencies</title>
+
+            <programlisting language="php"><![CDATA[
+// creating a cache object
+$cache = Zend_Cache::factory('Core',
+                             'File',
+                             array('lifetime' => 120,
+                                   'automatic_serialization' => true),
+                             array('cache_dir'
+                                       => dirname(__FILE__) . '/_files/'));
+Zend_Currency::setCache($cache);
+]]></programlisting>
+        </example>
+    </sect2>
+</sect1>

+ 120 - 0
documentation/manual/en/module_specs/Zend_Currency-Calculation.xml

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.calculation">
+    <title>Calculating with currencies</title>
+
+    <para>
+        When working with currencies you will sometimes also have to calculate with them.
+        <classname>Zend_Currency</classname> allows you to do this with some simple methods.
+        The following methods are supported for calculation:
+    </para>
+
+    <itemizedlist mark='opencircle'>
+        <listitem>
+            <para>
+                <emphasis><methodname>add()</methodname></emphasis>: This method adds the given
+                currency to the existing currency object.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>sub()</methodname></emphasis>: This method substracts the
+                given currency from the existing currency object.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>div()</methodname></emphasis>: This method divides the
+                given currency from the existing currency object.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>mul()</methodname></emphasis>: This method multiplies the
+                given currency with the existing currency object.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>mod()</methodname></emphasis>: This method calculates the
+                remaining value (modulo) from dividing the given currency from the existing
+                currency object.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>compare()</methodname></emphasis>: This method compares
+                the given currency with the existing currency object. When both values are
+                equal it returns '0'. When the existing currency value is greater than the
+                given, this method will return 1. Otherwise you will get '-1' returned.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>equals()</methodname></emphasis>: This method compares
+                the given currency with the existing currency object. When both values are
+                equal it returns <constant>TRUE</constant>, otherwise
+                <constant>FALSE</constant>.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>isMore()</methodname></emphasis>: This method compares
+                the given currency with the existing currency object. When the existing
+                currency is greater than the given one, you will get <constant>TRUE</constant>
+                in return, otherwise <constant>FALSE</constant>.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><methodname>isLess()</methodname></emphasis>: This method compares
+                the given currency with the existing currency object. When the existing
+                currency is less than the given one, you will get <constant>TRUE</constant>
+                in return, otherwise <constant>FALSE</constant>.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        As you can see the multiple methods allow any kind of calculation with
+        <classname>Zend_Currency</classname>. See the next snippets as example:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD',
+    )
+);
+
+print $currency; // Could return '$ 1.000,00'
+
+$currency->add(500);
+print $currency; // Could return '$ 1.500,00'
+]]></programlisting>
+
+    <programlisting language="php"><![CDATA[
+$currency_2 = new Zend_Currency(
+    array(
+        'value'    => 500,
+        'currency' => 'USD',
+    )
+);
+
+if ($currency->isMore($currency_2)) {
+    print "First is more";
+}
+
+$currency->div(5);
+print $currency; // Could return '$ 200,00'
+]]></programlisting>
+</sect1>

+ 171 - 0
documentation/manual/en/module_specs/Zend_Currency-Description.xml

@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.description">
+    <title>What makes a currency?</title>
+
+    <para>
+        The currency consists of several informations. A name, a abbreviation and a sign. Each
+        of these could be relevant to be displayed, but only one at the same time. It would not
+        be a good practice to display something like "USD 1.000 $".
+    </para>
+
+    <para>
+        Therefor <classname>Zend_Currency</classname> supports the definition of the currency
+        information which has to be rendered. The following constants can be used:
+    </para>
+
+    <table id="zend.currency.description.table-1">
+        <title>Rendered informations for a currency</title>
+
+        <tgroup cols="2" align="left">
+            <thead>
+                <row>
+                    <entry>Constant</entry>
+                    <entry>Description</entry>
+                </row>
+            </thead>
+
+            <tbody>
+                <row>
+                    <entry><constant>NO_SYMBOL</constant></entry>
+                    <entry>No currency representation will be rendered at all</entry>
+                </row>
+
+                <row>
+                    <entry><constant>USE_SYMBOL</constant></entry>
+
+                    <entry>
+                        The currency symbol will be rendered. For US Dollar this would be '$'
+                    </entry>
+                </row>
+
+                <row>
+                    <entry><constant>USE_SHORTNAME</constant></entry>
+
+                    <entry>
+                        The abbreviation for this currency will be rendered. For US Dollar this
+                        would be 'USD'. Most abbreviations consist of 3 characters
+                    </entry>
+                </row>
+
+                <row>
+                    <entry><constant>USE_NAME</constant></entry>
+
+                    <entry>
+                        The full name for this currency will be rendered. For US Dollar the full
+                        full name would be "US Dollar"
+                    </entry>
+                </row>
+            </tbody>
+        </tgroup>
+    </table>
+
+    <example id="zend.currency.description.example-1">
+        <title>Selecting the currency description</title>
+
+        <para>
+            Let's assume that your client has again set "en_US" as locale. Using no option the
+            returned value could look like this:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value' => 100,
+    )
+);
+
+print $currency; // Could return '$ 100'
+]]></programlisting>
+
+        <para>
+            By giving the proper option you can define what information which has to be
+            rendered.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'   => 100,
+        'display' => Zend_Currency::USE_SHORTNAME,
+    )
+);
+
+print $currency; // Could return 'USD 100'
+]]></programlisting>
+
+        <para>
+             Without providing the <property>display</property> the currency sign will be used
+            when rendering the object. When the currency has no sign, the abbreviation will be
+            used as replacement.
+        </para>
+    </example>
+
+    <note>
+        <title>Not all currencies have signs</title>
+
+        <para>
+            You should note that not all currencies have default currency signs. This means,
+            that when there is no default sign, and you set the sign to be rendered, you will
+            not have a rendered currency at all because the sign is an empty string.
+        </para>
+    </note>
+
+    <para>
+        Sometimes it is necessary to change the default informations. You can set each of the
+        three currency informations independently by giving the proper option. See the following
+        example.
+    </para>
+
+    <example id="zend.currency.description.example-2">
+        <title>Changing the currency description</title>
+
+        <para>
+            Let's assume that your client has again set "en_US" as locale. But now we don't want
+            to use the default settings but set our own description. This can simply be done
+            providing the proper option:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value' => 100,
+        'name'  => 'Dollar',
+    )
+);
+
+print $currency; // Could return 'Dollar 100'
+]]></programlisting>
+
+        <para>
+            You could also set a sign or an abbreviations yourself.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 100,
+        'symbol' => '$$$',
+    )
+);
+
+print $currency; // Could return '$$$ 100'
+]]></programlisting>
+    </example>
+
+    <note>
+        <title>Automatic display settings</title>
+
+        <para>
+            When you set a name, abbreviation or sign yourself, than this new information will
+            automatically be set to be rendered. This simplification prevents you from setting
+            the proper <property>display</property> option when you set a information.
+        </para>
+
+        <para>
+            So using the <property>sign</property> option you can omit
+            <property>display</property> and don't neet to setting it to
+            '<constant>USE_SYMBOL</constant>'.
+        </para>
+    </note>
+</sect1>

+ 107 - 0
documentation/manual/en/module_specs/Zend_Currency-Exchange.xml

@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.exchange">
+    <title>Exchanging currencies</title>
+
+    <para>
+        Within the previous section we discussed currency calculations. But as you can imaging
+        calculating currencies does often mean to calculate different currencies from different
+        countries.
+    </para>
+
+    <para>
+        In this case the currencies have to be exchanged so that both use the same currency.
+        Within real live this information is available by banks or by daily papers. But as we
+        are in web, we should use available exchange services.
+        <classname>Zend_Currency</classname> allows their usage with a simple callback.
+    </para>
+
+    <para>
+        First let's write a simple exchange service.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+class SimpleExchange implements Zend_Currency_CurrencyInterface
+{
+    public function getRate($from, $to)
+    {
+        if ($from !== "USD") {
+            throw new Exception('We can only exchange USD');
+        }
+
+        switch ($to) {
+            case 'EUR':
+                return 0.5;
+            case 'JPE':
+                return 0.7;
+       }
+
+       throw new Exception('Unable to exchange $to');
+    }
+}
+]]></programlisting>
+
+    <para>
+        We have now created a manual exchange service. It will not fit the real live, but it
+        shows you how currency exchange works.
+    </para>
+
+    <para>
+        Your exchange class must implement the
+        <classname>Zend_Currency_CurrencyInterface</classname> interface. This interface
+        requires the single method <methodname>getRate()</methodname> to be implemented. This
+        method has two parameters it will receive. Both are the short names for the given
+        currencies. <classname>Zend_Currency</classname> on the other side needs the exchange
+        rate to be returned.
+    </para>
+
+    <para>
+        In a living exchange class you would probably ask the service provider for the correct
+        exchange rates. For our example the manual rate will be ok.
+    </para>
+
+    <para>
+        Now we will simply attach our exchange class with <classname>Zend_Currency</classname>.
+        There are two ways to do this. Eigher by attaching a instance of the Exchange class, or
+        by simply giving a string with the classname.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD',
+    )
+);
+
+$service  = new SimpleExchange();
+
+// attach the exchange service
+$currency->setService($service);
+
+$currency_2 = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'EUR',
+    )
+);
+
+print $currency->add($currency2);
+]]></programlisting>
+
+    <para>
+        The above example will return '$ 3.000' because the 1.000 EUR will be converted by a
+        rate of 2 to 2.000 USD.
+    </para>
+
+    <note>
+        <title>Calculation without exchange service</title>
+
+        <para>
+            When you try to calculate two currency objects which do not use the same currency
+            and have no exchange service attached, you will get an exception. The reason is
+            that <classname>Zend_Currency</classname> is then not able to switch between the
+            different currencies.
+        </para>
+    </note>
+</sect1>

+ 25 - 23
documentation/manual/en/module_specs/Zend_Currency-Introduction.xml

@@ -1,23 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Reviewed: no -->
 <sect1 id="zend.currency.introduction">
-
     <title>Introduction to Zend_Currency</title>
 
     <para>
-        <classname>Zend_Currency</classname> is part of the strong support for i18n in Zend
-        Framework. It handles all issues related to currency, money representation and formatting.
-        It also provides additional methods which provide localized information on currencies, such
-        as which currency is used in which region.
+        <classname>Zend_Currency</classname> is part of the strong support for I18n in Zend
+        Framework. It handles all issues related to currency, money representation, formatting,
+        exchange services and calculation.
     </para>
 
     <sect2 id="zend.currency.introduction.list">
-
-        <title>Why use Zend_Currency?</title>
+        <title>Why should you use Zend_Currency?</title>
 
         <para>
-            <classname>Zend_Currency</classname> offers the following functions for handling
-            currency manipulations.
+            <classname>Zend_Currency</classname> offers you the following benefit:
         </para>
 
         <itemizedlist mark='opencircle'>
@@ -25,42 +21,48 @@
                 <para>
                     <emphasis>Complete Locale support</emphasis>
                 </para>
+
                 <para>
-                    <classname>Zend_Currency</classname> works with all available locales and
-                    therefore knows about over 100 different localized currencies. This includes
-                    currency names, abbreviations, money signs and more.
+                    This component works with all available locales and therefore knows about more
+                    than 100 different localized currencies. This includes informations like
+                    currency names, abbreviations, money signs and much more.
                 </para>
             </listitem>
+
             <listitem>
                 <para>
                     <emphasis>Reusable Currency Definitions</emphasis>
                 </para>
+
                 <para>
-                    <classname>Zend_Currency</classname> does not include the value of the
-                    currency. This is the reason why its functionality is not included in
-                    <classname>Zend_Locale_Format</classname>. <classname>Zend_Currency</classname>
-                    has the advantage that already defined currency representations can be reused.
+                    <classname>Zend_Currency</classname> has the advantage that already defined
+                    currency representations can be reused. You could also have 2 different
+                    representations for the same currency.
                 </para>
             </listitem>
+
             <listitem>
                 <para>
-                    <emphasis>Fluent Interface</emphasis>
+                    <emphasis>Currency calculation</emphasis>
                 </para>
+
                 <para>
-                    <classname>Zend_Currency</classname> includes fluent interfaces where possible.
+                    <classname>Zend_Currency</classname> allows you also to calculate with currency
+                    values. Therefor it provides you a interface to exchange services.
                 </para>
             </listitem>
+
             <listitem>
                 <para>
                     <emphasis>Additional Methods</emphasis>
                 </para>
+
                 <para>
-                    <classname>Zend_Currency</classname> includes additional methods that offer
-                    information about which regions a currency is used in or which currency is used
-                    in a specified region.
+                    <classname>Zend_Currency</classname> includes several additional methods that
+                    offer informations about details to currencies like: which currency is used
+                    within a defined region, or what are the known abbreviations of a currency.
                 </para>
             </listitem>
         </itemizedlist>
     </sect2>
-
-</sect1>
+</sect1>

+ 116 - 0
documentation/manual/en/module_specs/Zend_Currency-Number.xml

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.number">
+    <title>How does the currency look like?</title>
+
+    <para>
+        How the value of a currency will be rendered depends mainly on the used locale. There
+        are several informations which are set by the locale. Each of them can manually be
+        overridden by using the proper option.
+    </para>
+
+    <para>
+        For example, most locales are using the latin script for rendering numbers. But there
+        are languages like "Arabic" which are using other digits. And when you have an arabic
+        website you may also want to render other currencies by using the arabic script. See
+        the following example:
+    </para>
+
+    <example id="zend.currency.number.example-1">
+        <title>Using a custom script</title>
+
+        <para>
+            Let's expect that we are again using our "Dollar" currency. But now we want to
+            render our currency by using the arabic script.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'  => 1000,
+        'script' => 'Arab',
+    )
+);
+
+print $currency; // Could return '$ ١٬٠٠٠٫٠٠'
+]]></programlisting>
+    </example>
+
+    <para>
+        For more informations about available scripts look into
+        <classname>Zend_Locale</classname>'s <link linkend="zend.locale.numbersystems">chapter
+            about numbering systems</link>.
+    </para>
+
+    <para>
+        But also the formatting of a currency number (money value) can be changed. Per default
+        it depends on the used locale. It includes the separator which will be used between
+        thousands, which sign will be used as decimal point, and also the used precision.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD'
+        'format'   => 'de',
+    )
+);
+
+print $currency; // Could return '$ 1.000'
+]]></programlisting>
+
+    <para>
+        There are two ways to define the format which will be used. You can eighter give a
+        locale or define a format manually.
+    </para>
+
+    <para>
+        When you are using a locale for defining the format all is done automatically. The
+        locale 'de', for example, defines '.' as separator for thousands and ',' as decimal
+        point. Within english this is reversed.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$currency_1 = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD'
+        'format'   => 'de',
+    )
+);
+
+$currency_2 = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD'
+        'format'   => 'en',
+    )
+);
+
+print $currency_1; // Could return '$ 1.000'
+print $currency_2; // Could return '$ 1,000'
+]]></programlisting>
+
+    <para>
+        When you define it manually then you must conform the format as described in
+        <link linkend="zend.locale.number.localize.table-1">this chapter about
+            localizing</link>. See the following:
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD'
+        'format'   => '#0',
+    )
+);
+
+print $currency; // Could return '$ 1000'
+]]></programlisting>
+
+    <para>
+        In the above snippet we deleted the separator and also the precision.
+    </para>
+</sect1>

+ 171 - 0
documentation/manual/en/module_specs/Zend_Currency-Options.xml

@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.options">
+    <title>Options for currencies</title>
+
+    <para>
+        Depending on your needs, several options can be specified at instantiation. All of this
+        options have default values. But sometimes it is necessary to define how your currencies
+        will be rendered. This includes for example:
+    </para>
+
+    <itemizedlist mark='opencircle'>
+        <listitem>
+            <para>
+                <emphasis>Currency symbol, shortname or name</emphasis>:
+            </para>
+
+            <para>
+                <classname>Zend_Currency</classname> knows all currency names, abbreviations and
+                signs. But sometimes you could be in need to define the string which has to be
+                displayed as replacement for a currency.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis>Currency position</emphasis>:
+            </para>
+
+            <para>
+                The position of the currency symbol is automatically defined. But sometimes you
+                could be in need to define it manually.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis>Script</emphasis>:
+            </para>
+
+            <para>
+                You could define the script which shall be used to display digits. Detailed
+                information about scripts and their usage can be found in
+                <classname>Zend_Locale</classname>'s chapter <link
+                    linkend="zend.locale.numbersystems">Numeral System Conversion</link>.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis>Number formatting</emphasis>:
+            </para>
+
+            <para>
+                The amount of currency (generally known as money value) is formatted by
+                usaging the formatting rules defined by the locale. For example is the ','
+                sign in english used as separator for thousands, but in german as precision
+                sign.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        The following list mentions all options which could be set. They can eighter be set at
+        initiation or by using the <methodname>setFormat()</methodname> method. In any case
+        you have to give this options as array.
+    </para>
+
+    <itemizedlist mark='opencircle'>
+        <listitem>
+            <para>
+                <emphasis><property>currency</property></emphasis>: Defines the abbreviation
+                which can be displayed.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>display</property></emphasis>: Defines which part of the
+                currency should be used for displaying the currency representation. There are 4
+                representations which can be used and which are all described in <link
+                    linkend="zend.currency.usage.description">this
+                    table</link>.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>format</property></emphasis>: Defines the format which
+                should be used for displaying numbers. This number-format includes for example
+                the thousand separator. You can either use a default format by giving a locale
+                identifier, or define the number-format manually. If no format is set the locale
+                from the <classname>Zend_Currency</classname> object will be used. See <link
+                    linkend="zend.locale.number.localize.table-1">the chapter about number
+                    formatting</link> for details.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>locale</property></emphasis>: Defines a locale for this
+                currency. It will be used for detecting the default values when other settings
+                are omitted. Note that when you don't set a locale yourself, it will be detected
+                automatically which could lead to problems.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>name</property></emphasis>: Defines the full currency name
+                which can be displayed.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>position</property></emphasis>: Defines the position at
+                which the currency description should be displayed. The supported positions are
+                described <link
+                    linkend="zend.currency.usage.position">this this section</link>.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>precision</property></emphasis>: Defines the precision which
+                should be used for the currency representation. The default value depends on the
+                locale and is for most locales <emphasis>2</emphasis>.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>script</property></emphasis>: Defined which script should
+                be used for displaying digits. The default script for most locales is
+                <emphasis>'Latn'</emphasis>, which includes the digits 0 to 9. Other
+                scripts such as 'Arab' (Arabian) are using other digits. See <link
+                    linkend="zend.locale.numbersystems">the chapter about numbering
+                    systems</link> for details and available options.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>service</property></emphasis>: Defines the exchange service
+                which has to be used when calculating with different currencies.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>symbol</property></emphasis>: Defines the currency symbol
+                which can be displayed.
+            </para>
+        </listitem>
+
+        <listitem>
+            <para>
+                <emphasis><property>value</property></emphasis>: Defines the currency amount
+                (money value). Using this option you should also set the
+                <property>service</property> option.
+            </para>
+        </listitem>
+    </itemizedlist>
+
+    <para>
+        As you can see there is much which could be changed. Still as already mentioned the
+        default values for this settings conform the official standard for currency
+        represenation in every country.
+    </para>
+</sect1>

+ 87 - 0
documentation/manual/en/module_specs/Zend_Currency-Position.xml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.position">
+    <title>Where is the currency?</title>
+
+    <para>
+        The position where the currency sign or name will be displayed depends on the locale.
+        Still, when you want to define this setting yourself you have to use the
+        <property>display</property> option and provide one of the following constants:
+    </para>
+
+    <table id="zend.currency.position.table-1">
+        <title>Available positions for the currency</title>
+
+        <tgroup cols="2" align="left">
+            <thead>
+                <row>
+                    <entry>Constant</entry>
+                    <entry>Description</entry>
+                </row>
+            </thead>
+
+            <tbody>
+                <row>
+                    <entry><constant>STANDARD</constant></entry>
+                    <entry>Sets the standard position as defined within the locale</entry>
+                </row>
+
+                <row>
+                    <entry><constant>RIGHT</constant></entry>
+
+                    <entry>
+                        Displays the currency representation at the right side of the value
+                    </entry>
+                </row>
+
+                <row>
+                    <entry><constant>LEFT</constant></entry>
+
+                    <entry>
+                        Displays the currency representation at the left side of the value
+                    </entry>
+                </row>
+            </tbody>
+        </tgroup>
+    </table>
+
+    <example id="zend.currency.position.example-1">
+        <title>Setting the currency position</title>
+
+        <para>
+            Let's assume that your client has again set "en_US" as locale. Using no option the
+            returned value could look like this:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value' => 100,
+    )
+);
+
+print $currency; // Could return '$ 100'
+]]></programlisting>
+
+        <para>
+            So by using the default setting the currency (in our case $) could eighter be
+            rendered left or right from the value. Now let's define a fixed position:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 100,
+        'position' => Zend_Currency::RIGHT,
+    )
+);
+
+print $currency; // Could return '100 $';
+]]></programlisting>
+
+        <para>
+            Note that in the second snippet the position of USD is fixed regardless of the
+            used locale or currency.
+        </para>
+    </example>
+</sect1>

+ 55 - 526
documentation/manual/en/module_specs/Zend_Currency-Usage.xml

@@ -1,567 +1,96 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Reviewed: no -->
 <sect1 id="zend.currency.usage">
+    <title>Using Zend_Currency</title>
 
-    <title>How to Work with Currencies</title>
-
-    <para>
-        To use <classname>Zend_Currency</classname> within your application, create an instance of
-        it without any parameters. This will create an instance of
-        <classname>Zend_Currency</classname> with your locale set and defines the currency which
-        should be used for this locale.
-    </para>
-
-    <example id="zend.currency.usage.example1">
-
-        <title>Creating an Instance of Zend_Currency from the Locale</title>
+    <sect2 id="zend.currency.usage.generic">
+        <title>Generic usage</title>
 
         <para>
-            Assume you have 'en_US' set as the set locale by the user or your environment. By
-            passing no parameters while creating the instance you tell
-            <classname>Zend_Currency</classname> to use the currency from the locale 'en_US'. This
-            leads to an instance with US Dollar set as the currency with formatting rules from
-            'en_US'.
+            The simplest usecase within an application is to use the clients locale. When you create
+            a instance of <classname>Zend_Currency</classname> without giving any options, your
+            clients locale will be used to set the proper currency.
         </para>
 
-        <programlisting language="php"><![CDATA[
-$currency = new Zend_Currency();
-]]></programlisting>
-
-    </example>
-
-    <para>
-        <classname>Zend_Currency</classname> also supports the usage of an application-wide locale.
-        You can set a <classname>Zend_Locale</classname> instance in the registry as shown below.
-        With this notation you can avoid setting the locale manually for each instance when you want
-        to use the same locale throughout the application.
-    </para>
-
-    <programlisting language="php"><![CDATA[
-// in your bootstrap file
-$locale = new Zend_Locale('de_AT');
-Zend_Registry::set('Zend_Locale', $locale);
+        <example id="zend.currency.usage.generic.example-1">
+            <title>Creating a currency with client settings</title>
 
-// somewhere in your application
-$currency = new Zend_Currency();
-]]></programlisting>
-
-    <note>
-        <para>
-            If your system has no default locale, or if the locale of your system can not be
-            detected automatically, <classname>Zend_Currency</classname> will throw an exception. If
-            see this exception, you should consider setting the locale manually.
-        </para>
-    </note>
-
-    <para>
-        Depending on your needs, several parameters can be specified at instantiation. Each of
-        these parameters is optional and can be omitted. Even the order of the parameters can be
-        switched. The meaning of each parameter is described in this list:
-    </para>
-
-    <itemizedlist mark='opencircle'>
-        <listitem>
             <para>
-                <emphasis>currency</emphasis>:
+                Let's assume that your client has set "en_US" as wished language within his browser.
+                In this case <classname>Zend_Currency</classname> will automatically detect the
+                currency which has to be used.
             </para>
-            <para>
-                A locale can include several currencies. Therefore the first parameter
-                <emphasis>'currency'</emphasis> can define which currency should be used by giving
-                the short name or full name of that currency. If that currency in not recognized in
-                any locale an exception will be thrown. Currency short names are always made up of 3
-                letters, written in uppercase. Well known currency shortnames include
-                <acronym>USD</acronym> or <acronym>EUR</acronym>.
-            </para>
-        </listitem>
-        <listitem>
-            <para>
-                <emphasis>locale</emphasis>:
-            </para>
-            <para>
-                The <emphasis>'locale'</emphasis> parameter defines which locale should be
-                used for formatting the currency. The specified locale will also be used to get the
-                script and symbol for this currency if these parameters are not given.
-            </para>
-            <note>
-                <para>
-                    Note that <classname>Zend_Currency</classname> only accepts locales which
-                    include a region. This means that all locales that only include a language will
-                    result in an exception. For example the locale <emphasis>en</emphasis> will
-                    cause an exception to be thrown whereas the locale <emphasis>en_US</emphasis>
-                    will return <acronym>USD</acronym> as currency.
-                </para>
-            </note>
-        </listitem>
-    </itemizedlist>
-
-    <example id="zend.currency.usage.example2">
-
-        <title>Other Ways to Create Instances of Zend_Currency</title>
-
-        <programlisting language="php"><![CDATA[
-// expect standard locale 'de_AT'
-
-// creates an instance from 'en_US' using 'USD' which is default
-// currency for 'en_US'
-$currency = new Zend_Currency('en_US');
-
-// creates an instance from the set locale ('de_AT') using 'EUR' as
-// currency
-$currency = new Zend_Currency();
-
-// creates an instance using 'EUR' as currency, 'en_US' for number
-// formating
-$currency = new Zend_Currency('en_US', 'EUR');
-]]></programlisting>
-
-    </example>
-
-    <para>
-        You can omit any of the parameters to <classname>Zend_Currency</classname>'s constructor if
-        you want to use the default values. This has no negative effect on handling the currencies.
-        It can be useful if, for example, you don't know the default currency for a region.
-    </para>
-
-    <note>
-        <para>
-            For many countries there are several known currencies. Typically, one currency will
-            currently be in use, with one or more ancient currencies. If the
-            '<emphasis>currency</emphasis>' parameter is suppressed the contemporary currency will
-            be used. The region '<emphasis>de</emphasis>' for example knows the currencies
-            '<acronym>EUR</acronym>' and '<acronym>DEM</acronym>'... '<acronym>EUR</acronym>'
-            is the contemporary currency and will be used if the currency parameter is omitted.
-        </para>
-    </note>
-
-    <sect2 id="zend.currency.usage.tocurrency">
-
-        <title>Creating and Output String from a Currency</title>
-
-        <para>
-            To get a numeric value converted to an output string formatted for the currency at hand,
-            use the method <methodname>toCurrency()</methodname>. It takes the value which should be
-            converted. The value itself can be any normalized number.
-        </para>
-
-        <para>
-            If you have a localized number you will have to convert it first to an normalized number
-            with <link
-                linkend="zend.locale.number.normalize">Zend_Locale_Format::getNumber()</link>. It
-            may then be used with <methodname>toCurrency()</methodname> to create a currency output
-            string.
-        </para>
-
-        <para>
-            <methodname>toCurrency(array $options)</methodname> accepts an array with options which
-            can be used to temporarily set another format or currency representation. For details
-            about which options can be used see <link
-                linkend="zend.currency.usage.setformat">Changing the Format of a Currency</link>.
-        </para>
-
-        <example id="zend.currency.usage.tocurrency.example">
-
-            <title>Creating an Output String for a Currency</title>
 
             <programlisting language="php"><![CDATA[
-// creates an instance with 'en_US' using 'USD', which is the default
-// values for 'en_US'
-$currency = new Zend_Currency('en_US');
-
-// prints '$ 1,000.00'
-echo $currency->toCurrency(1000);
-
-// prints '$ 1.000,00'
-echo $currency->toCurrency(1000, array('format' => 'de_AT'));
+$currency = new Zend_Currency();
 
-// prints '$ ١٬٠٠٠٫٠٠'
-echo $currency->toCurrency(1000, array('script' => 'Arab'));
+// See the default settings which are depending on the client
+// var_dump($currency);
 ]]></programlisting>
 
+            <para>
+                The created object would now contain the currency "US Dollar" as this is the actual
+                assigned currency for US (United States). It has also other options set, like
+                "$" for the currency sign or "USD" for the abbreviation.
+            </para>
         </example>
-    </sect2>
-
-    <sect2 id="zend.currency.usage.setformat">
-
-        <title>Changing the Format of a Currency</title>
-
-        <para>
-            The format which is used by creation of a <classname>Zend_Currency</classname> instance
-            is, of course, the standard format. But occasionally it is necessary to change this
-            format.
-        </para>
-
-        <para>
-            The format of an currency output includes the following parts:
-        </para>
 
-        <itemizedlist mark='opencircle'>
-            <listitem>
-                <para>
-                    <emphasis>Currency symbol, shortname or name</emphasis>:
-                </para>
-                <para>
-                    The symbol of the currency is normally displayed within the currency output
-                    string. It can be suppressed when needed or even overwritten.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>Currency position</emphasis>:
-                </para>
-                <para>
-                    The position of the currency symbol is normally automatically defined by the
-                    locale. It can be changed if necessary.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>Script</emphasis>:
-                </para>
-                <para>
-                    The script which shall be used to display digits. Detailed information about
-                    scripts and their usage can be found in the documentation of
-                    <classname>Zend_Locale</classname> in the chapter <link
-                        linkend="zend.locale.numbersystems">Numeral System Conversion</link>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>Number formatting</emphasis>:
-                </para>
-                <para>
-                    The amount of currency (formally known as value of money) is formatted by the
-                    usage of formatting rules within the locale. For example is in English the ','
-                    sign used as separator for thousands, and in German the '.' sign.
-                </para>
-            </listitem>
-        </itemizedlist>
+        <note>
+            <title>Automatic locale detection does not always work</title>
 
-        <para>
-            So if you need to change the format, you should the <methodname>setFormat()</methodname>
-            method. It takes an array which should include every option you want to change. The
-            <varname>$options</varname> array supports the following settings:
-        </para>
-
-        <itemizedlist mark='opencircle'>
-            <listitem>
-                <para>
-                    <emphasis>position</emphasis>: Defines the position at which the currency
-                    description should be displayed. The supported positions can be found in <link
-                        linkend="zend.currency.usage.setformat.constantsposition">this table</link>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>script</emphasis>: Defined which script should be used for
-                    displaying digits. The default script for most locales is
-                    <emphasis>'Latn'</emphasis>, which includes the digits 0 to 9. Other
-                    scripts such as 'Arab' (Arabian) can be used.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>format</emphasis>: Defines the format which should be used for
-                    displaying numbers. This number-format includes for example the thousand
-                    separator. You can either use a default format by giving a locale identifier,
-                    or define the number-format manually. If no format is set the locale from the
-                    <classname>Zend_Currency</classname> object will be used.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>display</emphasis>: Defines which part of the currency should be
-                    used for displaying the currency representation. There are 4 representations
-                    which can be used and which are all described in <link
-                        linkend="zend.currency.usage.setformat.constantsdescription">this
-                        table</link>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>precision</emphasis>: Defines the precision which should be used for
-                    the currency representation. The default value is <emphasis>2</emphasis>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>name</emphasis>: Defines the full currency name which should be
-                    displayed. This option overwrites any currency name which is set through
-                    the creation of <classname>Zend_Currency</classname>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>currency</emphasis>: Defines the international abbreviation which
-                    should be displayed. This option overwrites any abbreviation which is set
-                    through the creation of <classname>Zend_Currency</classname>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis>symbol</emphasis>: Defines the currency symbol which should be
-                    displayed. This option overwrites any symbol which is set through
-                    the creation of <classname>Zend_Currency</classname>.
-                </para>
-            </listitem>
-        </itemizedlist>
-
-        <table id="zend.currency.usage.setformat.constantsdescription">
-
-            <title>Constants for the selecting the currency description</title>
-
-            <tgroup cols="2" align="left">
-                <thead>
-                    <row>
-                        <entry>constant</entry>
-                        <entry>description</entry>
-                    </row>
-                </thead>
-                <tbody>
-                    <row>
-                        <entry><constant>NO_SYMBOL</constant></entry>
-                        <entry>Do not display any currency representation</entry>
-                    </row>
-                    <row>
-                        <entry><constant>USE_SYMBOL</constant></entry>
-                        <entry>Display the currency symbol</entry>
-                    </row>
-                    <row>
-                        <entry><constant>USE_SHORTNAME</constant></entry>
-                        <entry>Display the 3 lettered international currency abbreviation</entry>
-                    </row>
-                    <row>
-                        <entry><constant>USE_NAME</constant></entry>
-                        <entry>Display the full currency name</entry>
-                    </row>
-                </tbody>
-            </tgroup>
-
-        </table>
-
-        <table id="zend.currency.usage.setformat.constantsposition">
-
-            <title>Constants for the selecting the position of the currency description</title>
-
-            <tgroup cols="2" align="left">
-                <thead>
-                    <row>
-                        <entry>constant</entry>
-                        <entry>description</entry>
-                    </row>
-                </thead>
-                <tbody>
-                    <row>
-                        <entry><constant>STANDARD</constant></entry>
-                        <entry>Set the standard position as defined within the locale</entry>
-                    </row>
-                    <row>
-                        <entry><constant>RIGHT</constant></entry>
-                        <entry>
-                            Display the currency representation at the right side of the value
-                        </entry>
-                    </row>
-                    <row>
-                        <entry><constant>LEFT</constant></entry>
-                        <entry>
-                            Display the currency representation at the left side of the value
-                        </entry>
-                    </row>
-                </tbody>
-            </tgroup>
-
-        </table>
-
-        <example id="zend.currency.usage.setformat.example">
-
-            <title>Changing the displayed format of a currency</title>
-
-            <programlisting language="php"><![CDATA[
-// creates an instance with 'en_US' using 'USD', 'Latin' and 'en_US' as
-// these are the default values from 'en_US'
-$currency = new Zend_Currency('en_US');
-
-// prints 'US$ 1,000.00'
-echo $currency->toCurrency(1000);
-
-$currency->setFormat(array('display' => Zend_Currency::USE_NAME,
-                           'position' => Zend_Currency::RIGHT));
-
-// prints '1.000,00 US Dollar'
-echo $currency->toCurrency(1000);
-
-$currency->setFormat(array('name' => 'American Dollar'));
-// prints '1.000,00 American Dollar'
-echo $currency->toCurrency(1000);
-
-$currency->setFormat(array('format' => '##0.00'));
-// prints '1000,00 American Dollar'
-echo $currency->toCurrency(1000);
-]]></programlisting>
+            <para>
+                You should note that this automatic locale detection does not always work properly.
+                The reason for this behaviour is that <classname>Zend_Currency</classname> must have
+                a locale which includes a region. When the client would only set "en" as locale
+                <classname>Zend_Currency</classname> would not know which of the more than 30
+                countries was meant. In this case an exception would be raised.
+            </para>
 
-        </example>
+            <para>
+                A client could also omit the locale settings within his browser. This would lead to
+                the problem that your environment settings will be used as fallback and could also
+                lead to an exception.
+            </para>
+        </note>
     </sect2>
 
-    <sect2 id="zend.currency.usage.informational">
-
-        <title>Reference Methods for Zend_Currency</title>
-
-        <para>
-            Of course, <classname>Zend_Currency</classname> supports also methods to get information
-            about any existing and many ancient currencies from <classname>Zend_Locale</classname>.
-            The supported methods are:
-        </para>
-
-        <itemizedlist mark='opencircle'>
-            <listitem>
-                <para>
-                    <emphasis><methodname>getSymbol()</methodname></emphasis>:
-                </para>
-                <para>
-                    Returns the known symbol of the set currency or a given currency. For example
-                    <emphasis>$</emphasis> for the US Dollar within the locale
-                    '<emphasis>en_US</emphasis>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis><methodname>getShortName()</methodname></emphasis>:
-                </para>
-                <para>
-                    Returns the abbreviation of the set currency or a given currency. For example
-                    <acronym>USD</acronym> for the US Dollar within the locale
-                    '<emphasis>en_US</emphasis>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis><methodname>getName()</methodname></emphasis>:
-                </para>
-                <para>
-                    Returns the full name of the set currency of a given currency. For example
-                    <emphasis>US Dollar</emphasis> for the US Dollar within the locale
-                    '<emphasis>en_US</emphasis>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis><methodname>getRegionList()</methodname></emphasis>:
-                </para>
-                <para>
-                    Returns a list of regions where the set currency or a given one is known to be
-                    used. It is possible that a currency is used within several regions, so the
-                    return value is always an array.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    <emphasis><methodname>getCurrencyList()</methodname></emphasis>:
-                </para>
-                <para>
-                    Returns a list of currencies which are used in the given region.
-                </para>
-            </listitem>
-        </itemizedlist>
+    <sect2 id="zend.currency.usage.locale">
+        <title>Currency creation based on a locale</title>
 
         <para>
-            The function <methodname>getSymbol()</methodname>,
-            <methodname>getShortName()</methodname> and <methodname>getName()</methodname> accept
-            two optional parameters. If no parameter is given the
-            expected data will be returned from the set currency. The first parameter takes the
-            shortname of a currency. Short names are always three lettered, for example
-            <acronym>EUR</acronym> for euro or <acronym>USD</acronym> for US Dollar. The second
-            parameter defines from which locale the data should be read. If no locale is given, the
-            set locale is used.
+            To prevent the problems with your client you could simply set the wished locale
+            manually.
         </para>
 
-        <example id="zend.currency.usage.informational.example">
-
-            <title>Getting Information about Currencies</title>
-
-            <programlisting language="php"><![CDATA[
-// creates an instance with 'en_US' using 'USD', 'Latin' and 'en_US'
-// as these are the default values from 'en_US'
+        <programlisting language="php"><![CDATA[
 $currency = new Zend_Currency('en_US');
 
-// prints '$'
-echo $currency->getSymbol();
-
-// prints 'EUR'
-echo $currency->getShortName('EUR');
-
-// prints 'Österreichische Schilling'
-echo $currency->getName('ATS', 'de_AT');
-
-// returns an array with all regions where USD is used
-print_r($currency->getRegionList();
+// You can also use the 'locale' option
+// $currency = new Zend_Currency(array('locale' => 'en_US'));
 
-// returns an array with all currencies which were ever used in this
-// region
-print_r($currency->getCurrencyList('de_AT');
+// See the actual settings which are fixed to 'en_US'
+// var_dump($currency);
 ]]></programlisting>
 
-        </example>
-
-    </sect2>
-
-    <sect2 id="zend.currency.usage.setlocale">
-
-        <title>Settings new default values</title>
-
         <para>
-            The method <methodname>setLocale()</methodname> allows to set a new locale for
-            <classname>Zend_Currency</classname>. All default values for the currency will be
-            overwritten when this method is invoked. This includes currency name, abbreviation and
-            symbol.
+            As within our first example the used currency will be "US Dollar". But now we are no
+            longer dependend on the clients settings.
         </para>
 
-        <example id="zend.currency.usage.setlocale.example">
-
-            <title>Setting a New Locale</title>
-
-            <programlisting language="php"><![CDATA[
-// get the currency for US
-$currency = new Zend_Currency('en_US');
-print $currency->toCurrency(1000);
-
-// get the currency for AT
-$currency->setLocale('de_AT');
-print $currency->toCurrency(1000);
-]]></programlisting>
-        </example>
-
-    </sect2>
-
-    <sect2 id="zend.currency.usage.cache">
-
-        <title>Zend_Currency Performance Optimization</title>
-
         <para>
-            <classname>Zend_Currency</classname>'s performance can be optimized using
-            <classname>Zend_Cache</classname>. The static method
-            <methodname>Zend_Currency::setCache($cache)</methodname> accepts one option: a
-            <classname>Zend_Cache</classname> adapter. If the cache adapter is set, the localization
-            data that <classname>Zend_Currency</classname> uses are cached. There are some static
-            methods for manipulating the cache: <methodname>getCache()</methodname>,
-            <methodname>hasCache()</methodname>, <methodname>clearCache()</methodname> and
-            <methodname>removeCache()</methodname>.
+            <classname>Zend_Currency</classname> also supports the usage of an application-wide
+            locale. You can set a <classname>Zend_Locale</classname> instance in the registry as
+            shown below. With this notation you can avoid setting the locale manually for each
+            instance when you want to use the same locale throughout the application.
         </para>
 
-        <example id="zend.currency.usage.cache.example">
-
-            <title>Caching currencies</title>
+        <programlisting language="php"><![CDATA[
+// in your bootstrap file
+$locale = new Zend_Locale('de_AT');
+Zend_Registry::set('Zend_Locale', $locale);
 
-            <programlisting language="php"><![CDATA[
-// creating a cache object
-$cache = Zend_Cache::factory('Core',
-                             'File',
-                             array('lifetime' => 120,
-                                   'automatic_serialization' => true),
-                             array('cache_dir'
-                                       => dirname(__FILE__) . '/_files/'));
-Zend_Currency::setCache($cache);
+// somewhere in your application
+$currency = new Zend_Currency();
 ]]></programlisting>
-        </example>
-
     </sect2>
-
 </sect1>

+ 110 - 0
documentation/manual/en/module_specs/Zend_Currency-Value.xml

@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect1 id="zend.currency.value">
+    <title>How much is my currency?</title>
+
+    <para>
+        When you are working with currencies then you normally want to display an amount of
+        money. And when you work with different currencies then you have to do this with three
+        different things. The amount you want to display, the precision you want to use, and
+        probably the exchange rate.
+    </para>
+
+    <sect2 id="zend.currency.value.money">
+        <title>Working with currency values</title>
+
+        <para>
+            The currency value, a.k.a. the money, you want to use can easily be set by using the
+            <property>value</property> option.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD',
+    )
+);
+
+print $currency; // Could return '$ 1.000'
+]]></programlisting>
+
+        <para>
+            Using the <methodname>setFormat()</methodname> method with this array option, and
+            also by using the <methodname>setValue()</methodname> method you can set the value
+            afterwards.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD',
+    )
+);
+
+print $currency->setValue(2000); // Could return '$ 2.000'
+]]></programlisting>
+
+        <para>
+            With the <methodname>getValue()</methodname> method you will get the actual set
+            value.
+        </para>
+    </sect2>
+
+    <sect2 id="zend.currency.value.precision">
+        <title>Using precision on currencies</title>
+
+        <para>
+            When working with currencies they you probably also have to handle precision.
+            Most currencies use a precision of 2. This means that when you have 100 US dollars
+            you could also have 50 cents. The related value is simply a floating value.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000.50,
+        'currency' => 'USD',
+    )
+);
+
+print $currency; // Could return '$ 1.000,50'
+]]></programlisting>
+
+        <para>
+            Of course, as the default precision is 2, you will get '00' for the decimal value
+            when there is no precision to display.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'    => 1000,
+        'currency' => 'USD',
+    )
+);
+
+print $currency; // Could return '$ 1.000,00'
+]]></programlisting>
+
+        <para>
+            To get rid of this default precision you could simply use the
+            <property>precision</property> option and set it to '0'. And you can set any other
+            precision you want to use between 0 and 9. All values will be rounded or streched
+            when they don't fit the set precision.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency(
+    array(
+        'value'     => 1000,30,
+        'currency'  => 'USD',
+        'precision' => 0
+    )
+);
+
+print $currency; // Could return '$ 1.000'
+]]></programlisting>
+    </sect2>
+</sect1>

+ 291 - 37
library/Zend/Currency.php

@@ -60,6 +60,8 @@ class Zend_Currency
      * 'currency'  => 3 lettered international abbreviation
      * 'symbol'    => Currency symbol
      * 'locale'    => Locale for this currency
+     * 'value'     => Money value
+     * 'service'   => Exchange service to use
      *
      * @var array
      * @see Zend_Locale
@@ -73,41 +75,52 @@ class Zend_Currency
         'name'      => null,
         'currency'  => null,
         'symbol'    => null,
-        'locale'    => null
+        'locale'    => null,
+        'value'     => 0,
+        'service'   => null
     );
 
     /**
      * Creates a currency instance. Every supressed parameter is used from the actual or the given locale.
      *
-     * @param  string             $currency OPTIONAL currency short name
-     * @param  string|Zend_Locale $locale   OPTIONAL locale name
+     * @param  string|array       $options OPTIONAL Options array or currency short name
+     *                                              when string is given
+     * @param  string|Zend_Locale $locale  OPTIONAL locale name
      * @throws Zend_Currency_Exception When currency is invalid
      */
-    public function __construct($currency = null, $locale = null)
+    public function __construct($options = null, $locale = null)
     {
-        if (Zend_Locale::isLocale($currency, true, false)) {
-            $temp     = $locale;
-            $locale   = $currency;
-            $currency = $temp;
+        if (is_array($options)) {
+            $this->setFormat($options);
+        } else if (Zend_Locale::isLocale($options, false, false)) {
+            $temp    = $locale;
+            $locale  = $options;
+            $options = $temp;
         }
 
         $this->setLocale($locale);
-
         // Get currency details
-        $this->_options['currency'] = self::getShortName($currency, $this->_options['locale']);
-        $this->_options['name']     = self::getName($currency, $this->_options['locale']);
-        $this->_options['symbol']   = self::getSymbol($currency, $this->_options['locale']);
+        if (!isset($options['currency']) || !is_array($options)) {
+            $this->_options['currency'] = self::getShortName($options, $this->_options['locale']);
+        }
+
+        if (!isset($this->_options['name']) || !is_array($options)) {
+            $this->_options['name']     = self::getName($options, $this->_options['locale']);
+        }
+
+        if (!isset($this->_options['symbol']) || !is_array($options)) {
+            $this->_options['symbol']   = self::getSymbol($options, $this->_options['locale']);
+        }
 
         if (($this->_options['currency'] === null) and ($this->_options['name'] === null)) {
             require_once 'Zend/Currency/Exception.php';
-            throw new Zend_Currency_Exception("Currency '$currency' not found");
+            throw new Zend_Currency_Exception("Currency '$options' not found");
         }
 
         // Get the format
-        $this->_options['display']  = self::NO_SYMBOL;
-        if (empty($this->_options['symbol']) === false) {
+        if (!empty($this->_options['symbol'])) {
             $this->_options['display'] = self::USE_SYMBOL;
-        } else if (empty($this->_options['currency']) === false) {
+        } else if (!empty($this->_options['currency'])) {
             $this->_options['display'] = self::USE_SHORTNAME;
         }
     }
@@ -115,15 +128,30 @@ class Zend_Currency
     /**
      * Returns a localized currency string
      *
-     * @param  integer|float $value   Currency value
+     * @param  integer|float $value   OPTIONAL Currency value
      * @param  array         $options OPTIONAL options to set temporary
      * @throws Zend_Currency_Exception When the value is not a number
      * @return string
      */
-    public function toCurrency($value, array $options = array())
+    public function toCurrency($value = null, array $options = array())
     {
+        if ($value === null) {
+            if (is_array($value) && isset($options['value'])) {
+                $value = $options['value'];
+            } else {
+                $value = $this->_options['value'];
+            }
+        }
+
+        if (is_array($value)) {
+            $options += $value;
+            if (isset($options['value'])) {
+                $value = $options['value'];
+            }
+        }
+
         // Validate the passed number
-        if ((isset($value) === false) or (is_numeric($value) === false)) {
+        if (!(isset($value)) or (is_numeric($value) === false)) {
             require_once 'Zend/Currency/Exception.php';
             throw new Zend_Currency_Exception("Value '$value' has to be numeric");
         }
@@ -150,7 +178,6 @@ class Zend_Currency
             $format = Zend_Locale_Data::getContent($format, 'currencynumber');
         }
 
-        $symbols  = Zend_Locale_Data::getList($locale, 'symbols');
         $original = $value;
         $value    = Zend_Locale_Format::toNumber($value, array('locale'        => $locale,
                                                                'number_format' => $format,
@@ -435,7 +462,7 @@ class Zend_Currency
      */
     public function toString()
     {
-        return (empty($this->_options['name']) === false) ? $this->_options['name'] : $this->_options['currency'];
+        return $this->toCurrency();
     }
 
     /**
@@ -513,10 +540,16 @@ class Zend_Currency
     {
         require_once 'Zend/Locale.php';
         try {
-            $this->_options['locale'] = Zend_Locale::findLocale($locale);
+            $locale = Zend_Locale::findLocale($locale);
+            if (strlen($locale) > 4) {
+                $this->_options['locale'] = $locale;
+            } else {
+                require_once 'Zend/Currency/Exception.php';
+                throw new Zend_Currency_Exception("No region found within the locale '" . (string) $locale . "'");
+            }
         } catch (Zend_Locale_Exception $e) {
             require_once 'Zend/Currency/Exception.php';
-            throw new Zend_Currency_Exception($e->getMessage(), 0, $e);
+            throw new Zend_Currency_Exception($e->getMessage());
         }
 
         // Get currency details
@@ -538,6 +571,239 @@ class Zend_Currency
     }
 
     /**
+     * Returns the value
+     *
+     * @return float
+     */
+    public function getValue()
+    {
+        return $this->_options['value'];
+    }
+
+    /**
+     * Adds a currency
+     *
+     * @param float|integer|Zend_Currency $value    Add this value to currency
+     * @param string|Zend_Currency        $currency The currency to add
+     * @return Zend_Currency
+     */
+    public function setValue($value, $currency = null)
+    {
+        $this->_options['value'] = $this->_exchangeCurrency($value, $currency);
+        return $this;
+    }
+
+    /**
+     * Adds a currency
+     *
+     * @param float|integer|Zend_Currency $value    Add this value to currency
+     * @param string|Zend_Currency        $currency The currency to add
+     * @return Zend_Currency
+     */
+    public function add($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        $this->_options['value'] += (float) $value;
+        return $this;
+    }
+
+    /**
+     * Substracts a currency
+     *
+     * @param float|integer|Zend_Currency $value    Substracts this value from currency
+     * @param string|Zend_Currency        $currency The currency to substract
+     * @return Zend_Currency
+     */
+    public function sub($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        $this->_options['value'] -= (float) $value;
+        return $this;
+    }
+
+    /**
+     * Divides a currency
+     *
+     * @param float|integer|Zend_Currency $value    Divides this value from currency
+     * @param string|Zend_Currency        $currency The currency to divide
+     * @return Zend_Currency
+     */
+    public function div($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        $this->_options['value'] /= (float) $value;
+        return $this;
+    }
+
+    /**
+     * Multiplies a currency
+     *
+     * @param float|integer|Zend_Currency $value    Multiplies this value from currency
+     * @param string|Zend_Currency        $currency The currency to multiply
+     * @return Zend_Currency
+     */
+    public function mul($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        $this->_options['value'] *= (float) $value;
+        return $this;
+    }
+
+    /**
+     * Calculates the modulo from a currency
+     *
+     * @param float|integer|Zend_Currency $value    Calculate modulo from this value
+     * @param string|Zend_Currency        $currency The currency to calculate the modulo
+     * @return Zend_Currency
+     */
+    public function mod($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        $this->_options['value'] %= (float) $value;
+        return $this;
+    }
+
+    /**
+     * Compares two currencies
+     *
+     * @param float|integer|Zend_Currency $value    Compares the currency with this value
+     * @param string|Zend_Currency        $currency The currency to compare this value from
+     * @return Zend_Currency
+     */
+    public function compare($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        $value = $this->_options['value'] - $value;
+        if ($value < 0) {
+            return -1;
+        } else if ($value > 0) {
+            return 1;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Returns true when the two currencies are equal
+     *
+     * @param float|integer|Zend_Currency $value    Compares the currency with this value
+     * @param string|Zend_Currency        $currency The currency to compare this value from
+     * @return boolean
+     */
+    public function equals($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        if ($this->_options['value'] == $value) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true when the currency is more than the given value
+     *
+     * @param float|integer|Zend_Currency $value    Compares the currency with this value
+     * @param string|Zend_Currency        $currency The currency to compare this value from
+     * @return boolean
+     */
+    public function isMore($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        if ($this->_options['value'] > $value) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true when the currency is less than the given value
+     *
+     * @param float|integer|Zend_Currency $value    Compares the currency with this value
+     * @param string|Zend_Currency        $currency The currency to compare this value from
+     * @return boolean
+     */
+    public function isLess($value, $currency = null)
+    {
+        $value = $this->_exchangeCurrency($value, $currency);
+        if ($this->_options['value'] < $value) {
+            return true;
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Internal method which calculates the exchanges currency
+     *
+     * @param float|integer|Zend_Currency $value    Compares the currency with this value
+     * @param string|Zend_Currency        $currency The currency to compare this value from
+     * @return unknown
+     */
+    protected function _exchangeCurrency($value, $currency)
+    {
+        if ($value instanceof Zend_Currency) {
+            $value = $value->getValue();
+        }
+
+        $currency = $this->getShortName($currency);
+        $rate     = 1;
+        if ($currency !== $this->getShortName()) {
+            $service = $this->getService();
+            if (!($service instanceof Zend_Currency_CurrencyInterface)) {
+                require_once 'Zend/Currency/Exception.php';
+                throw new Zend_Currency_Exception('No exchange service applied');
+            }
+
+            $rate = $service->getRate($this->getShortName(), $currency);
+        }
+
+        $value *= $rate;
+        return $value;
+    }
+
+    /**
+     * Returns the set service class
+     *
+     * @return Zend_Service
+     */
+    public function getService()
+    {
+        return $this->_options['service'];
+    }
+
+    /**
+     * Sets a new exchange service
+     *
+     * @param string|Zend_Currency_CurrencyInterface $service Service class
+     * @return Zend_Currency
+     */
+    public function setService($service)
+    {
+        if (is_string($service)) {
+            require_once 'Zend/Loader.php';
+            if (!class_exists($service)) {
+                $file = str_replace('_', DIRECTORY_SEPARATOR, $service) . '.php';
+                if (Zend_Loader::isReadable($file)) {
+                    Zend_Loader::loadClass($class);
+                }
+            }
+
+            $service = new $service;
+        }
+
+        if (!($service instanceof Zend_Currency_CurrencyInterface)) {
+            require_once 'Zend/Currency/Exception.php';
+            throw new Zend_Currency_Exception('A currency service must implement Zend_Currency_CurrencyInterface');
+        }
+
+        $this->_options['service'] = $service;
+        return $this;
+    }
+
+    /**
      * Internal method for checking the options array
      *
      * @param  array $options Options to check
@@ -549,7 +815,7 @@ class Zend_Currency
      * @throws Zend_Currency_Exception On unknown options
      * @return array
      */
-    private function _checkOptions(array $options = array())
+    protected function _checkOptions(array $options = array())
     {
         if (count($options) === 0) {
             return $this->_options;
@@ -605,23 +871,11 @@ class Zend_Currency
                         Zend_Locale_Format::convertNumerals(0, $options['script']);
                     } catch (Zend_Locale_Exception $e) {
                         require_once 'Zend/Currency/Exception.php';
-                        throw new Zend_Currency_Exception($e->getMessage(), 0, $e);
+                        throw new Zend_Currency_Exception($e->getMessage());
                     }
                     break;
 
-                case 'name':
-                    // Break intentionally omitted
-                case 'currency':
-                    // Break intentionally omitted
-                case 'locale':
-                    // Break intentionally omitted
-                case 'symbol':
-                    // Unchecked options
-                    break;
-
                 default:
-                    require_once 'Zend/Currency/Exception.php';
-                    throw new Zend_Currency_Exception("Unknown option: '$name' = '$value'");
                     break;
             }
         }

+ 39 - 0
library/Zend/Currency/CurrencyInterface.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category  Zend
+ * @package   Zend_Currency
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ * @version   $Id: Exception.php 16971 2009-07-22 18:05:45Z mikaelkael $
+ */
+
+/**
+ * Exception class for Zend_Currency
+ *
+ * @category  Zend
+ * @package   Zend_Currency
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   http://framework.zend.com/license/new-bsd     New BSD License
+ */
+interface Zend_Currency_CurrencyInterface
+{
+    /**
+     * Returns the actual exchange rate
+     *
+     * @param string $from Short Name of the base currency
+     * @param string $to   Short Name of the currency to exchange to
+     */
+    public function getRate($from, $to);
+}

+ 49 - 0
tests/Zend/Currency/ExchangeTest.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Currency
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id:$
+ */
+
+/**
+ * Zend_Date
+ */
+require_once 'Zend/Currency/CurrencyInterface.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Currency
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @group      Zend_Currency
+ */
+class ExchangeTest implements Zend_Currency_CurrencyInterface
+{
+    /**
+     * Test method for exchange rate
+     *
+     * @param string $from
+     * @param string $to
+     * @return float
+     */
+    public function getRate($from, $to)
+    {
+        return 2;
+    }
+}

+ 163 - 11
tests/Zend/CurrencyTest.php

@@ -92,13 +92,13 @@ class Zend_CurrencyTest extends PHPUnit_Framework_TestCase
 
         try {
             $currency = new Zend_Currency('de_XX');
-            $this->fail("locale should always include region and therefor not been recognised");
+            $this->fail("Locale without region should not been recognised");
         } catch (Zend_Currency_Exception $e) {
             // success
         }
+
         try {
             $currency = new Zend_Currency('xx_XX');
-            $this->fail("unknown locale should not have been recognised");
         } catch (Zend_Currency_Exception $e) {
             // success
         }
@@ -407,13 +407,6 @@ class Zend_CurrencyTest extends PHPUnit_Framework_TestCase
             $this->assertContains("Unknown script", $e->getMessage());
         }
 
-        try {
-            $USD->setFormat(array('unknown' => 'unknown'));
-            $this->fail("Exception expected");
-        } catch (Zend_Currency_Exception $e) {
-            $this->assertContains("Unknown option", $e->getMessage());
-        }
-
         $USD->setFormat(array('precision' => null));
 
         try {
@@ -549,8 +542,8 @@ class Zend_CurrencyTest extends PHPUnit_Framework_TestCase
     public function testToString()
     {
         $USD = new Zend_Currency('USD','en_US');
-        $this->assertSame('US Dollar', $USD->toString());
-        $this->assertSame('US Dollar', $USD->__toString());
+        $this->assertSame('$0.00', $USD->toString());
+        $this->assertSame('$0.00', $USD->__toString());
     }
 
     /**
@@ -631,4 +624,163 @@ class Zend_CurrencyTest extends PHPUnit_Framework_TestCase
         $currency = new Zend_Currency("USD", "de_DE");
         $this->assertEquals('2,3000 $', $currency->toCurrency(2.3, array('precision' => 4)));
     }
+
+    /**
+     * Testing options at initiation
+     */
+    public function testOptionsWithConstructor()
+    {
+        $currency = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT'));
+        $this->assertEquals('de_AT', $currency->getLocale());
+        $this->assertEquals('EUR', $currency->getShortName());
+    }
+
+    /**
+     * Testing value at initiation
+     */
+    public function testValueWithConstructor()
+    {
+        $currency = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $this->assertEquals('de_AT', $currency->getLocale());
+        $this->assertEquals('EUR', $currency->getShortName());
+        $this->assertEquals('€ 100,00', $currency->toCurrency());
+    }
+
+    /**
+     * Add values
+     */
+    public function testAddValues()
+    {
+        $currency = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT'));
+        $currency->add(100);
+        $this->assertEquals('€ 100,00', $currency->toCurrency());
+
+        $currency->add(100)->add(100);
+        $this->assertEquals('€ 300,00', $currency->toCurrency());
+    }
+
+    /**
+     * Substract values
+     */
+    public function testSubValues()
+    {
+        $currency = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT'));
+        $currency->sub(100);
+        $this->assertEquals('-€ 100,00', $currency->toCurrency());
+
+        $currency->sub(100)->sub(100);
+        $this->assertEquals('-€ 300,00', $currency->toCurrency());
+    }
+
+    /**
+     * Multiply values
+     */
+    public function testMulValues()
+    {
+        $currency = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT'));
+        $currency->add(100);
+        $currency->mul(2);
+        $this->assertEquals('€ 200,00', $currency->toCurrency());
+
+        $currency->mul(2)->mul(2);
+        $this->assertEquals('€ 800,00', $currency->toCurrency());
+    }
+
+    /**
+     * Divide values
+     */
+    public function testDivValues()
+    {
+        $currency = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT'));
+        $currency->add(800);
+        $currency->div(2);
+        $this->assertEquals('€ 400,00', $currency->toCurrency());
+
+        $currency->div(2)->div(2);
+        $this->assertEquals('€ 100,00', $currency->toCurrency());
+    }
+
+    /**
+     * Modulo values
+     */
+    public function testModValues()
+    {
+        $currency = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT'));
+        $currency->add(801);
+        $currency->mod(2);
+        $this->assertEquals('€ 1,00', $currency->toCurrency());
+    }
+
+    /**
+     * Compare values
+     */
+    public function testCompareValues()
+    {
+        $currency  = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $currency2 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $this->assertEquals(0, $currency->compare($currency2));
+
+        $currency3 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 101));
+        $this->assertEquals(-1, $currency->compare($currency3));
+
+        $currency4 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 99));
+        $this->assertEquals(1, $currency->compare($currency4));
+    }
+
+    /**
+     * Equals values
+     */
+    public function testEqualsValues()
+    {
+        $currency  = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $currency2 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $this->assertTrue($currency->equals($currency2));
+
+        $currency3 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 101));
+        $this->assertFalse($currency->equals($currency3));
+    }
+
+    /**
+     * IsMore values
+     */
+    public function testIsMoreValues()
+    {
+        $currency  = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $currency2 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $this->assertFalse($currency->isMore($currency2));
+
+        $currency3 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 99));
+        $this->assertTrue($currency->isMore($currency3));
+    }
+
+    /**
+     * IsLess values
+     */
+    public function testIsLessValues()
+    {
+        $currency  = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $currency2 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $this->assertFalse($currency->isLess($currency2));
+
+        $currency3 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 101));
+        $this->assertTrue($currency->isLess($currency3));
+    }
+
+    /**
+     * Exchange tests
+     */
+    public function testExchangeValues()
+    {
+        $currency  = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+        $currency2 = new Zend_Currency(array('currency' => 'EUR', 'locale' => 'de_AT', 'value' => 100));
+
+        require_once 'Currency/ExchangeTest.php';
+
+        $this->assertEquals(null, $currency->getService());
+        $currency->setService(new ExchangeTest());
+        $this->assertTrue($currency->getService() instanceof Zend_Currency_CurrencyInterface);
+
+        $currency->setService('ExchangeTest');
+        $this->assertTrue($currency->getService() instanceof Zend_Currency_CurrencyInterface);
+    }
 }