<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.mobile.push.mpns">
    <title>Zend_Mobile_Push_Mpns</title>

    <para>
        <classname>Zend_Mobile_Push_Mpns</classname> provides the ability to
        send push notifications to Windows Phone.  MPNS allows the sending of
        3 different types of notifications; which common behavior is in the
        <classname>Zend_Mobile_Push_Message_Mpns</classname> base.  Followed by
        specific classes for Raw, Toast and Tile notifications.
    </para>

    <sect2 id="zend.mobile.push.mpns.server">
        <title>Pushing Messages</title>

        <note>
            <para>Prior to pushing messages; you must implement the practices
                outlined on <ulink
                url="http://msdn.microsoft.com/en-us/library/hh202940(v=VS.92).aspx">Receiving
                Push Notifications for Windows Phone</ulink>. 
            </para>
        </note>

        <para>
            When implementing MPNS; you have several components that
            you will utilize.  <classname>Zend_Mobile_Push_Mpns</classname>
            which contains the server components and
            <classname>Zend_Mobile_Push_Message_Mpns_Raw</classname> which
            allows you to send <ulink
            url="http://msdn.microsoft.com/en-us/library/hh202977(v=VS.92).aspx">raw
            notifications</ulink>,
            <classname>Zend_Mobile_Push_Message_Mpns_Toast</classname> which
            allows you to send <ulink
            url="http://msdn.microsoft.com/en-us/library/hh202967(v=VS.92).aspx">toast
            notifications</ulink>, and
            <classname>Zend_Mobile_Push_Message_Mpns_Tile</classname> which
            allows you to send <ulink
            url="http://msdn.microsoft.com/en-us/library/hh202970(v=VS.92).aspx">tile
            notifications</ulink>.  Each message sent must do an HTTP request;
            so remember this when sending in large batches.
        </para>

        <para>
            The actual implementation of the code is fairly minimal; however,
            considerations to error handling must be taken.
        </para>

        <programlisting language="php"><![CDATA[
$mpns = new Zend_Mobile_Push_Mpns();
$messages = array();

// raw notification
$message = new Zend_Mobile_Push_Message_Mpns_Raw();
$message->setToken('http://sn1.notify.live.net/throttledthirdparty/01.00/THETOKEN');
$message->setMessage('<notification><foo id="bar" /></notification>');
$messages[] = $message;

// toast message
$message = new Zend_Mobile_Push_Message_Mpns_Toast();
$message->setToken('http://sn1.notify.live.net/throttledthirdparty/01.00/THETOKEN');
$message->setTitle('Foo');
$message->setMessage('Bar');
$messages[] = $message;

// tile message
$message = new Zend_Mobile_Push_Mpns_Tile();
$message->setToken('http://sn1.notify.live.net/throttledthirdparty/01.00/THETOKEN');
$message->setBackgroundImage('foo.bar');
$message->setCount(1);
$message->setTitle('Bar Foo');
$messages[] = $message;

foreach ($messages as $m) {
    try {
        $mpns->send($m);
    } catch (Zend_Mobile_Push_Exception_InvalidToken $e) {
        echo 'Remove token: ' . $m->getToken() . PHP_EOL;
    } catch (Zend_Mobile_Push_Exception $e) {
        echo 'Error occurred, token: ' . $m->getToken() . ' - ' . $e->getMessage() . PHP_EOL;
    }
}
]]></programlisting>

        <table id="zend.mobile.push.mpns.server.exceptions">
            <title>Exceptions and Remediation Techniques</title>
            <tgroup cols="3" align="left" colsep="1" rowsep="1">
                <thead>
                    <row>
                        <entry>Exception</entry>
                        <entry>Meaning</entry>
                        <entry>Handling</entry>
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry>Zend_Mobile_Push_Exception</entry>
                        <entry>These types of exceptions are more generic in nature
                        and are thrown either from MPNS or internally on input
                        validation</entry>
                        <entry>Read the message and determine remediation steps.</entry>
                    </row>
                    <row>
                        <entry>Zend_Mobile_Push_Exception_DeviceQuotaExceeded</entry>
                        <entry>You have sent too many messages to this device;
                            you may retry again later.</entry>
                        <entry>Try again later or implement <ulink
                                url="http://en.wikipedia.org/wiki/Exponential_backoff">
                            Exponential Backoff
                        </ulink>.</entry>
                    </row>
                    <row>
                        <entry>Zend_Mobile_Push_Exception_InvalidPayload</entry>
                        <entry>Generally the payload will not throw an exception
                        unless the size of the payload is too large or it is missing
                        required content.</entry>
                        <entry>Check the size of the payload is within the
                        requirements of MPNS</entry>
                    </row>
                    <row>
                        <entry>Zend_Mobile_Push_Exception_InvalidToken</entry>
                        <entry>Any form of an invalid token will be if the
                            device is no longer subscribed, inactive or not
                            valid.</entry>
                        <entry>In some cases you may attempt to resend in an
                            hour; this will be stated in the exception.
                            Otherwise you will want to remove the token from
                            being sent to again.</entry>
                    </row>
                    <row>
                        <entry>Zend_Mobile_Push_Exception_QuotaExceeded</entry>
                        <entry>You have reached the per-day throttling.</entry>
                        <entry>Per-day throttling is only on unauthenticated web
                        services; you will need to <ulink
                        url="http://msdn.microsoft.com/en-us/library/ff941099(v=vs.92).aspx">register
                        your application for notifications</ulink>.</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>
    </sect2>

    <sect2 id="zend.mobile.push.mpns.message">

        <title>Advanced Messages</title>

        <para>
            MPNS provides the ability for sending more advanced messages; for
            instance the examples above show the most basic implementation of a
            message.  Zend_Mobile_Push_Message_Mpns_* allows you to do far more
            advanced messaging outlined below.
        </para>

        <sect3 id="zend.mobile.push.mpns.message.tile">

            <title>Tile Messages</title>

            <para>
                Tile messages have additional optional attributes for Windows
                Phone 7.1+; you must ensure that you are sending to a device
                with the proper version otherwise your notification will fail.
            </para>

            <programlisting language="php"><![CDATA[
$message = new Zend_Mobile_Push_Message_Mpns_Tile();
$message->setToken('http://sn1.notify.live.net/throttledthirdparty/01.00/THETOKEN'); // REPLACE WITH NOTIFICATION URI FROM MPNS
$message->setBackgroundImage('foo.jpg');
$message->setCount(1);
$message->setTitle('Bar');

// other optional attributes for wp7.1+
$message->setTileId('/Foo.xaml');
$message->setBackBackgroundImage('blue.jpg');
$message->setBackTitle('Bar');
$message->setBackContent('Foo Bar');
    ]]></programlisting>

        </sect3>

        <sect3 id="zend.mobile.push.mpns.message.toast">

            <title>Toast Messages</title>

            <para>
                Toast messages have additional optional attributes for Windows
                Phone 7.1+; you must ensure that you are sending to a device
                with the proper version otherwise your notification will fail.
            </para>

            <programlisting language="php"><![CDATA[
$message = new Zend_Mobile_Push_Message_Mpns_Toast();
$message->setToken('http://sn1.notify.live.net/throttledthirdparty/01.00/THETOKEN'); // REPLACE WITH NOTIFICATION URI FROM MPNS
$message->setTitle('Foo');
$message->setMessage('Bar');

// optional attributes for wp7.1+
$message->setParams('?bar=foo'); //optional parameters
]]></programlisting>

        </sect3>
    </sect2>
</sect1>
