Services_Apns
[ class tree: Services_Apns ] [ index: Services_Apns ] [ all elements ]

Source for file Client.php

Documentation is available at Client.php

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * This file contains an abstraction implementation
  7.  * used to query Apple Push Notifications Service (APNS)
  8.  *
  9.  * This file contaions an abstraction layer
  10.  * implementation used to query Apple Push Notifications Service.
  11.  * 
  12.  * PHP version 5
  13.  *
  14.  * LICENSE:
  15.  *
  16.  * Copyright (c) 2013, Yahav Gindi Bar; Pear Technology Investments, Ltd.
  17.  * All rights reserved.
  18.  *
  19.  * Redistribution and use in source and binary forms, with or without
  20.  * modification, are permitted provided that the following conditions
  21.  * are met:
  22.  *
  23.  *  * Redistributions of source code must retain the above copyright
  24.  *    notice, this list of conditions and the following disclaimer.
  25.  *  * Redistributions in binary form must reproduce the above copyright
  26.  *    notice, this list of conditions and the following disclaimer in
  27.  *    the documentation and/or other materials provided with the distribution.
  28.  *  * Neither the name of the PHP_LexerGenerator nor the names of its
  29.  *    contributors may be used to endorse or promote products derived
  30.  *    from this software without specific prior written permission.
  31.  *
  32.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  33.  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  34.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  35.  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  36.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  37.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  38.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  39.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  40.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  41.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  *
  44.  *
  45.  * @category  Services
  46.  * @package   Services_Apns
  47.  * @author    Yahav Gindi Bar <g.b.yahav@gmail.com>
  48.  * @copyright 2013 Yahav Gindi Bar
  49.  * @license   http://www.php.net/license/3_01.txt  PHP License 3.01
  50.  * @version   SVN: $Id$
  51.  * @link      https://github.com/YahavGB/Services_APNS
  52.  */
  53.  
  54. // {{{ Load the exceptions class
  55.  
  56. /**
  57.  * Load the APNS service exceptions class
  58.  */
  59. require_once 'Services/Apns/Exception.php';
  60.  
  61. // }}}
  62.  
  63. // {{{ Services_Apns_Client
  64.  
  65. /**
  66.  * Short description for class
  67.  *
  68.  * This class provides an abstraction layer
  69.  * implementation used to query Apple Push Notifications Service.
  70.  * 
  71.  * Each class extended from this abstract class
  72.  * should implement a specific APNS gateway.
  73.  * 
  74.  * As I'm writing this class, there're two available gateways:
  75.  * The messaging gateway and the feedback gateway.
  76.  *
  77.  * @category  Services
  78.  * @package   Services_Apns
  79.  * @author    Yahav Gindi Bar <g.b.yahav@gmail.com>
  80.  * @copyright 2013 Yahav Gindi Bar
  81.  * @license   http://www.php.net/license/3_01.txt  PHP License 3.01
  82.  * @version   Release: 0.1.0
  83.  * @link      https://github.com/YahavGB/Services_APNS
  84.  */
  85. abstract class Services_Apns_Client
  86. {    
  87.     // {{{ constants
  88.  
  89.     /**
  90.     * Constat used with {@link Services_Apns_Client::connect}.
  91.     * Used to specify to use sandbox as the environment.
  92.     * @var int 
  93.     */
  94.     const ENV_SANDBOX = 1;
  95.     
  96.     /**
  97.      * Constat used with {@link Services_Apns_Client::connect}.
  98.      * Used to specify to use production as the environment.
  99.      * @var int 
  100.      */
  101.     const ENV_PRODUCTION = 2;
  102.     
  103.     /**
  104.      * Specifiying the connection socket default timeout
  105.      * @var int 
  106.      */
  107.     const SOCKET_DEFAULT_TIMEOUT = 30;
  108.     
  109.     /**
  110.      * The number of bytes to read
  111.      * each time from the stream.
  112.      * @var int 
  113.      */
  114.     const SOCKET_READ_BYTES = 8192;
  115.     
  116.     // }}}
  117.     
  118.     // {{{ Properties
  119.     
  120.     /**
  121.     * The default environment
  122.     * @var int 
  123.     */
  124.     protected $defaultEnvironment = self::ENV_PRODUCTION;
  125.     
  126.     /**
  127.     * Is the stream socket connected
  128.     * @var boolean 
  129.     */
  130.     protected $isConnected = false;
  131.     
  132.     /**
  133.     * The stream socket handler
  134.     * @var resource 
  135.     */
  136.     protected $socketHandler = null;
  137.     
  138.     /**
  139.     * The file path to the authorized SSL certificate provided by Apple
  140.     * @var string 
  141.     */
  142.     protected $sslCertFilePath = '';
  143.     
  144.     /**
  145.     * The password pharse
  146.     * @var string 
  147.     */
  148.     protected $passPhrase = null;
  149.     
  150.     // }}}
  151.     
  152.     // {{{ Abstract methods
  153.  
  154.     /**
  155.     * Get the APNS sandbox uri to query
  156.     *
  157.     * @return string 
  158.     */
  159.     protected abstract function getApnsProductionUri();
  160.     
  161.     /**
  162.     * Get the APNS sandbox uri to query
  163.     * 
  164.     * @return string 
  165.     */
  166.     protected abstract function getApnsSandboxUri();
  167.     
  168.     // }}}
  169.     
  170.     // {{{ dtor
  171.     
  172.     /**
  173.     * Class destructor:
  174.     * used to dispose the connection, in case it was opened
  175.     * 
  176.     * @return void 
  177.     */
  178.     public function __destruct()
  179.     {
  180.         $this->close();
  181.     }
  182.     
  183.     // }}}
  184.     
  185.     // {{{ connect()
  186.     
  187.     /**
  188.     * Open the connection to Apple Push Notifications service
  189.     * 
  190.     * @param int $environment The environment value
  191.     * 
  192.     * @return Services_Apns_Client 
  193.     */
  194.     public function connect($environment = null)
  195.     {
  196.         if ($this->isConnected()) {
  197.             throw new Services_Apns_Exception(
  198.                 'Connection has already been opened and must be firstly closed'
  199.             );
  200.         }
  201.         
  202.         if ($environment === null{
  203.             $environment $this->defaultEnvironment;
  204.         }
  205.         
  206.         if ($environment != self::ENV_SANDBOX
  207.             && $environment != self::ENV_PRODUCTION
  208.         {
  209.             throw new Services_Apns_Exception(
  210.                 'The $environment value must be '
  211.                 . 'Services_Apns_Client::ENV_SANDBOX or '
  212.                 . 'Services_Apns_Client::ENV_PRODUCTION.'
  213.             );
  214.         }
  215.     
  216.         if (empty($this->sslCertFilePath)) {
  217.             throw new Services_Apns_Exception(
  218.                 'Before connecting to the service,'
  219.                 . ' you must firstly set up your authorized SSL certificate.'
  220.             );
  221.         }
  222.     
  223.         $sslOptions = array(
  224.             'local_cert' => $this->sslCertFilePath,
  225.         );
  226.         
  227.         if ($this->passPhrase !== null{
  228.             $sslOptions['passphrase'$this->passPhrase;
  229.         }
  230.         
  231.         if ($environment == self::ENV_SANDBOX{
  232.             $this->initConnection($this->getApnsSandboxUri()$sslOptions);
  233.         else {
  234.             $this->initConnection($this->getApnsProductionUri()$sslOptions);
  235.         }
  236.         
  237.         $this->isConnected = true;
  238.         return $this;
  239.     }
  240.     
  241.     // }}}
  242.     
  243.     // {{{ close()
  244.     
  245.     /**
  246.     * Close the connection to the APNS gateway
  247.     * 
  248.     * @return Services_ApnsAbstractGateway 
  249.     */
  250.     public function close()
  251.     {
  252.         if ($this->isConnected && is_resource($this->socketHandler)) {
  253.             fclose($this->socketHandler);
  254.         }
  255.         
  256.         $this->isConnected = false;
  257.         return $this;
  258.     }
  259.     
  260.     // }}}
  261.     
  262.     // {{{ initConnection($gatewayAddress, $sslData)
  263.     
  264.     /**
  265.     * Initialize the connection to the APNS gateway
  266.     * 
  267.     * @param string $gatewayAddress The gateway URI address
  268.     * @param array  $sslData        Additional SSL data to assign to the stream
  269.     * 
  270.     * @return Services_ApnsAbstractGateway 
  271.     */
  272.     protected function initConnection($gatewayAddressarray $sslData
  273.     {
  274.         if (($timeout = ini_get('socket_timeout')) === false{
  275.             $timeout = self::SOCKET_DEFAULT_TIMEOUT;
  276.         }
  277.         
  278.         
  279.         $this->socketHandler = stream_socket_client(
  280.             $gatewayAddress,
  281.             $errno,
  282.             $errstr,
  283.             $timeout,
  284.             STREAM_CLIENT_CONNECT,
  285.             stream_context_create(
  286.                 array(
  287.                     'ssl' => $sslData,
  288.                 )
  289.             )
  290.         );
  291.         
  292.         if (!$this->socketHandler{
  293.             throw new Services_Apns_Exception(
  294.                 'Enable to connect to Apple Push Notifications Service.'
  295.                 . PHP_EOL . $errstr '(code: ' $errno
  296.                 . ', gateway address: ' $gatewayAddress ')'
  297.             );
  298.         }
  299.         
  300.         stream_set_blocking($this->socketHandler0);
  301.         stream_set_write_buffer($this->socketHandler0);
  302.         return $this;
  303.     }
  304.     
  305.     // }}}
  306.     
  307.     // {{{ read()
  308.     
  309.     /**
  310.     * Read bytes from the APNS gateway stream
  311.     * 
  312.     * @return string|null
  313.     */
  314.     protected function read()
  315.     {
  316.         if (!$this->isConnected()) {
  317.             throw new Services_Apns_Exception(
  318.                 'The connection to Apple Push Notifications Service is not opened.'
  319.             );
  320.         }
  321.         
  322.         $data = null;
  323.         if (!feof($this->socket)) {
  324.             $data fread($this->socketself::SOCKET_READ_BYTES);
  325.         }
  326.         return $data;
  327.     }
  328.     
  329.     // }}}
  330.     
  331.     // {{{ write($data)
  332.  
  333.     /**
  334.     * Writes the given data to the socket stream
  335.     * 
  336.     * @param string $data The data (payload) to write to the stream
  337.     * 
  338.     * @return int 
  339.     */
  340.     protected function write($data)
  341.     {
  342.         if (!$this->isConnected()) {
  343.             throw new Services_Apns_Exception(
  344.                 'The connection to Apple Push Notifications Service is not opened.'
  345.             );
  346.         }
  347.         return @fwrite($this->socketHandler$data);
  348.     }
  349.     
  350.     // }}}
  351.     
  352.     // {{{ Getters & Setters
  353.     
  354.     /**
  355.     * Set the file path to the authorized SSL certificate provided by Apple
  356.     * 
  357.     * @param string $filePath The SSL certificate file path
  358.     * 
  359.     * @return Services_ApnsAbstractGateway 
  360.     */
  361.     public function setSslCertificateFilePath($filePath)
  362.     {
  363.         // Enable to reset the file path to a null value.
  364.         if ($filePath === null{
  365.             $this->sslCertFilePath = null;
  366.             return $this;
  367.         }
  368.         
  369.         if (!is_string($filePath)) {
  370.             throw new Services_Apns_Exception(
  371.                 'The given file path must be a string.'
  372.             );
  373.         }
  374.         
  375.         if (empty($filePath)) {
  376.             throw new Services_Apns_Exception(
  377.                 'The given file path can not be empty.'
  378.             );
  379.         }
  380.         
  381.         if (!file_exists($filePath)) {
  382.             throw new Services_Apns_Exception(
  383.                 'The given certificate file path does not exists.'
  384.             );
  385.         }
  386.         
  387.         $this->sslCertFilePath = $filePath;
  388.         return $this;
  389.     }
  390.     
  391.     /**
  392.     * Get the file path to the authorized SSL certificate provided by Apple
  393.     * 
  394.     * @return string 
  395.     */
  396.     public function getSslCertificateFilePath()
  397.     {
  398.         return $this->sslCertFilePath;
  399.     }
  400.  
  401.     /**
  402.     * Set the password phrase
  403.     * 
  404.     * @param string $phrase The password phrase
  405.     * 
  406.     * @return Services_ApnsAbstractGateway 
  407.     */
  408.     public function setPasswordPhrase($phrase)
  409.     {
  410.         if (!is_scalar($phrase)) {
  411.             throw new Services_Apns_Exception(
  412.                 'The given phrase must be a scalar type.'
  413.             );
  414.         }
  415.         
  416.         $this->passPhrase = $phrase;
  417.         return $this;
  418.     }
  419.     
  420.     /**
  421.     * Gets the password phrase
  422.     * 
  423.     * @return string 
  424.     */
  425.     public function getPasswordPhrase()
  426.     {
  427.         return $this->passPhrase;
  428.     }
  429.     
  430.     /**
  431.     * Set the default environment
  432.     * 
  433.     * @param int $value The default environment value
  434.     * 
  435.     * @return Services_ApnsAbstractGateway 
  436.     */
  437.     public function setDefaultEnvironment($value)
  438.     {
  439.         if (!is_int($value)) {
  440.             throw new Services_Apns_Exception(
  441.                 'The given value must be an int type.'
  442.             );
  443.         }
  444.         
  445.         if ($value != self::ENV_SANDBOX
  446.             && $value != self::ENV_PRODUCTION
  447.         {
  448.             throw new Services_Apns_Exception(
  449.                 'The $environment value must be '
  450.                 . 'Services_Apns_Client::ENV_SANDBOX or '
  451.                 . 'Services_Apns_Client::ENV_PRODUCTION.'
  452.             );
  453.         }
  454.     
  455.         $this->defaultEnvironment = $value;
  456.         return $this;
  457.     }
  458.     
  459.     /**
  460.     * Gets the default environment
  461.     * 
  462.     * @return string 
  463.     */
  464.     public function getDefaultEnvironment()
  465.     {
  466.         return $this->defaultEnvironment;
  467.     }
  468.     
  469.     /**
  470.     * Gets the value that indicates if the stream
  471.     * currently connected to the APNS gateway.
  472.     * 
  473.     * @return boolean 
  474.     */
  475.     public function isConnected()
  476.     {
  477.         return $this->isConnected;
  478.     }
  479.     
  480.     // }}}
  481. }
  482.  
  483. // }}}
  484.  
  485. /*
  486.  * Local variables:
  487.  * tab-width: 4
  488.  * c-basic-offset: 4
  489.  * c-hanging-comment-ender-p: nil
  490.  * End:
  491.  */

Documentation generated on Tue, 19 Feb 2013 14:30:02 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.