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

Source for file Growl.php

Documentation is available at Growl.php

  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2006, Bertrand Mansion                                  |
  4. // | All rights reserved.                                                  |
  5. // |                                                                       |
  6. // | Redistribution and use in source and binary forms, with or without    |
  7. // | modification, are permitted provided that the following conditions    |
  8. // | are met:                                                              |
  9. // |                                                                       |
  10. // | o Redistributions of source code must retain the above copyright      |
  11. // |   notice, this list of conditions and the following disclaimer.       |
  12. // | o Redistributions in binary form must reproduce the above copyright   |
  13. // |   notice, this list of conditions and the following disclaimer in the |
  14. // |   documentation and/or other materials provided with the distribution.|
  15. // | o The names of the authors may not be used to endorse or promote      |
  16. // |   products derived from this software without specific prior written  |
  17. // |   permission.                                                         |
  18. // |                                                                       |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
  30. // |                                                                       |
  31. // +-----------------------------------------------------------------------+
  32. // | Author: Bertrand Mansion <golgote@mamasam.com>                        |
  33. // +-----------------------------------------------------------------------+
  34.  
  35. require_once 'PEAR.php';
  36. require_once 'Net/Growl/Application.php';
  37.  
  38. /**#@+
  39.  * Growl defines
  40.  */
  41. /**
  42.  * Growl default UDP port
  43.  */
  44. if (!defined('GROWL_UDP_PORT')) define('GROWL_UDP_PORT'9887);
  45. /**
  46.  * Version of the Growl protocol used in this package
  47.  */
  48. if (!defined('GROWL_PROTOCOL_VERSION')) define('GROWL_PROTOCOL_VERSION'1);
  49. /**
  50.  * Packet of type Registration
  51.  */
  52. if (!defined('GROWL_TYPE_REGISTRATION')) define('GROWL_TYPE_REGISTRATION'0);
  53. /**
  54.  * Packet of type Notification
  55.  */
  56. if (!defined('GROWL_TYPE_NOTIFICATION')) define('GROWL_TYPE_NOTIFICATION'1);
  57. /**#@-*/
  58. /**#@+
  59.  * Package defines
  60.  */
  61. /**
  62.  * Current number of notification being displayed on user desktop
  63.  */
  64. $GLOBALS['_NET_GROWL_NOTIFICATION_COUNT'= 0;
  65. /**
  66.  * Maximum number of notification to be displayed on user desktop
  67.  */
  68. if (!isset($GLOBALS['_NET_GROWL_NOTIFICATION_LIMIT'])) {
  69.     $GLOBALS['_NET_GROWL_NOTIFICATION_LIMIT'= 0;
  70. }
  71. /**#@-*/
  72.  
  73. /**
  74.  * Sends notifications to {@link http://growl.info Growl}
  75.  * 
  76.  * This package makes it possible to easily send a notification from
  77.  * your PHP script to {@link http://growl.info Growl}.
  78.  *
  79.  * Growl is a global notification system for Mac OS X.
  80.  * Any application can send a notification to Growl, which will display
  81.  * an attractive message on your screen. Growl currently works with a
  82.  * growing number of applications.
  83.  * 
  84.  * The class provides the following capabilities:
  85.  * - Register your PHP application in Growl.
  86.  * - Let Growl know what kind of notifications to expect.
  87.  * - Notify Growl.
  88.  * - Set a maximum number of notifications to be displayed.
  89.  *
  90.  * @author    Bertrand Mansion <golgote@mamasam.com>
  91.  * @copyright 2006
  92.  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
  93.  * @package   Net_Growl
  94.  * @link      http://growl.info Growl Homepage
  95.  */
  96. class Net_Growl extends PEAR
  97. {
  98.     /**
  99.      * PHP application object
  100.      * 
  101.      * This is usually a Net_Growl_Application object but can really be
  102.      * any other object as long as Net_Growl_Application methods are
  103.      * implemented.
  104.      *
  105.      * @var object 
  106.      * @access private
  107.      */
  108.     var $_application;
  109.  
  110.     /**
  111.      * Socket resource
  112.      * @var resource 
  113.      * @access private
  114.      */
  115.     var $_socket;
  116.  
  117.     /**
  118.      * Application is registered
  119.      * @var bool 
  120.      * @access private
  121.      */
  122.     var $_isRegistered = false;
  123.  
  124.     /**
  125.      * Net_Growl connection options
  126.      * @var array 
  127.      * @access private
  128.      */
  129.     var $_options = array(
  130.                         'host' => '127.0.0.1',
  131.                         'port' => GROWL_UDP_PORT,
  132.                         'protocol' => 'udp'
  133.                         );
  134.     /**
  135.      * Singleton
  136.      *
  137.      * Makes sure there is only one Growl connection open.
  138.      *
  139.      * @return object Net_Growl 
  140.      */
  141.     function &singleton($appName$notifications$password ''$options = array())
  142.     {
  143.         static $obj;
  144.         
  145.         if (!isset($obj)) {
  146.             $obj = new Net_Growl($appName$notifications$password$options);
  147.         }
  148.         return $obj;
  149.     }
  150.  
  151.     /**
  152.      * Constructor
  153.      *
  154.      * This method instantiate a new Net_Growl object and opens a socket connection
  155.      * to the specified Growl socket server. Currently, only UDP is supported by Growl.
  156.      * The constructor registers a shutdown function {@link Net_Growl::_Net_Growl()}
  157.      * that closes the socket if it is open.
  158.      * 
  159.      * Example 1.
  160.      * <code>
  161.      * require_once 'Net/Growl.php';
  162.      *
  163.      * $notifications = array('Errors', 'Messages');
  164.      * $growl = new Net_Growl('My application', $notification);
  165.      * $growl->notify( 'Messages',
  166.      *                 'My notification title',
  167.      *                 'My notification description');
  168.      * </code>
  169.      *
  170.      * @param  mixed    Can be a Net_Growl_Application object or the application name string
  171.      * @param  array    Array of notifications
  172.      * @param  string   Optional password for Growl
  173.      * @param  array    Array of options : 'host', 'port', 'protocol' for Growl socket server
  174.      * @access public
  175.      */
  176.     function Net_Growl(&$application$notifications = array()$password ''$options = array())
  177.     {
  178.         foreach ($options as $k => $v{
  179.             if (isset($this->_options[$k])) {
  180.                 $this->_options[$k$v;
  181.             }
  182.         }
  183.         if (is_string($application)) {
  184.             $this->_application =new Net_Growl_Application($application$notifications$password);
  185.         elseif (is_object($application)) {
  186.             $this->_application =$application;
  187.         }
  188.         parent::PEAR();
  189.     }
  190.  
  191.     /**
  192.      * Limit the number of notifications
  193.      *
  194.      * This method limits the number of notifications to be displayed on
  195.      * the Growl user desktop. By default, there is no limit. It is used
  196.      * mostly to prevent problem with notifications within loops.
  197.      *
  198.      * @access  public
  199.      * @param   int     Maximum number of notifications
  200.      */
  201.     function setNotificationLimit($max)
  202.     {
  203.         $GLOBALS['_NET_GROWL_NOTIFICATION_LIMIT'$max;
  204.     }
  205.  
  206.     /**
  207.      * Returns the registered application object
  208.      * @access public
  209.      * @return object Application 
  210.      * @see Net_Growl_Application
  211.      */
  212.     function &getApplication()
  213.     {
  214.         return $this->_application;
  215.     }
  216.  
  217.     /**
  218.      * Build, encode end send the registration packet
  219.      *
  220.      * @access  private
  221.      * @return true|PEAR_Error
  222.      */
  223.     function _sendRegister()
  224.     {
  225.         if (!isset($this->_socket)) {
  226.             $socket $this->_options['protocol'].'://'.$this->_options['host'];
  227.             $this->_socket fsockopen($socket$this->_options['port']$errno$errstr);
  228.             if ($this->_socket === false{
  229.                 return PEAR::raiseError($errstr);
  230.             }
  231.         }
  232.  
  233.         $appName       utf8_encode($this->_application->getGrowlName());
  234.         $password      $this->_application->getGrowlPassword();
  235.         $nameEnc       $defaultEnc '';
  236.         $nameCnt       $defaultCnt = 0;
  237.         $notifications $this->_application->getGrowlNotifications();
  238.  
  239.         foreach($notifications as $name => $options{
  240.             if (is_array($options&& !empty($options['enabled'])) {
  241.                 $defaultEnc .= pack('c'$nameCnt);
  242.                 ++$defaultCnt;
  243.             }
  244.  
  245.             $name utf8_encode($name);
  246.             $nameEnc .= pack('n'strlen($name)).$name;
  247.             ++$nameCnt;
  248.  
  249.         }
  250.         $data pack('c2nc2',
  251.                         GROWL_PROTOCOL_VERSION,
  252.                         GROWL_TYPE_REGISTRATION,
  253.                         strlen($appName),
  254.                         $nameCnt,
  255.                         $defaultCnt);
  256.  
  257.         $data .= $appName $nameEnc $defaultEnc;
  258.     
  259.         if (!empty($password)) {
  260.             $checksum pack('H32'md5($data $password));
  261.         else {
  262.             $checksum pack('H32'md5($data));
  263.         }
  264.         $data .= $checksum;
  265.  
  266.         $res fwrite($this->_socket$datastrlen($data));
  267.         if ($res === false{
  268.             return PEAR::raiseError('Could not send registration to Growl Server.');
  269.         }
  270.         $this->_isRegistered = true;
  271.         return true;
  272.     }
  273.  
  274.     /**
  275.      * Sends a notification to Growl
  276.      *
  277.      * Growl notifications have a name, a title, a description and
  278.      * a few options, depending on the kind of display plugin you use.
  279.      * The bubble plugin is recommended, until there is a plugin more
  280.      * appropriate for these kind of notifications.
  281.      *
  282.      * The current options supported by most Growl plugins are:
  283.      * <pre>
  284.      * array('priority' => 0, 'sticky' => false)
  285.      * </pre>
  286.      * - sticky: whether the bubble stays on screen until the user clicks on it.
  287.      * - priority: a number from -2 (low) to 2 (high), default is 0 (moderate).
  288.      *
  289.      * @access  public
  290.      * @param   object      Application object
  291.      * @param   bool        Whether to send the registration to the server
  292.      * @return true|PEAR_Error
  293.      */
  294.     function notify($name$title$description ''$options = array())
  295.     {
  296.         if ($GLOBALS['_NET_GROWL_NOTIFICATION_LIMIT'> 0 &&
  297.             $GLOBALS['_NET_GROWL_NOTIFICATION_COUNT'>= $GLOBALS['_NET_GROWL_NOTIFICATION_LIMIT']{
  298.             return true;
  299.         }
  300.  
  301.         if (!$this->_isRegistered && ($res $this->_sendRegister()) !== true{
  302.             return $res;
  303.         }
  304.  
  305.         $appName     utf8_encode($this->_application->getGrowlName());
  306.         $password    $this->_application->getGrowlPassword();
  307.         $name        utf8_encode($name);
  308.         $title       utf8_encode($title);
  309.         $description utf8_encode($description);
  310.         $priority    = isset($options['priority']$options['priority': 0;
  311.  
  312.         $flags ($priority 7* 2;
  313.       
  314.         if ($priority < 0{
  315.             $flags |= 8;
  316.         }
  317.         if (isset($options['sticky']&& $options['sticky'=== true{
  318.             $flags $flags | 1;
  319.         }
  320.  
  321.         $data pack('c2n5',
  322.                         GROWL_PROTOCOL_VERSION,
  323.                         GROWL_TYPE_NOTIFICATION,
  324.                         $flags,
  325.                         strlen($name),
  326.                         strlen($title),
  327.                         strlen($description),
  328.                         strlen($appName));
  329.  
  330.         $data .= $name $title $description $appName;
  331.  
  332.         if (!empty($password)) {
  333.             $checksum pack('H32'md5($data $password));
  334.         else {
  335.             $checksum pack('H32'md5($data));
  336.         }
  337.         $data .= $checksum;
  338.  
  339.         $res fwrite($this->_socket$datastrlen($data));
  340.         if ($res === false{
  341.             return PEAR::raiseError('Could not send notification to Growl Server.');
  342.         }
  343.         ++$GLOBALS['_NET_GROWL_NOTIFICATION_COUNT'];
  344.         return true;
  345.     }
  346.  
  347.     /**
  348.      * Destructor
  349.      *
  350.      * Automatically closes the socket if it is open.
  351.      *
  352.      * @access  private
  353.      */
  354.     function _Net_Growl()
  355.     {
  356.         if (is_resource($this->_socket)) {
  357.             fclose($this->_socket);
  358.             $this->_socket = null;
  359.         }
  360.     }
  361. }
  362. ?>

Documentation generated on Mon, 11 Mar 2019 14:38:44 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.