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

Source for file Driver.php

Documentation is available at Driver.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors:   Carsten Lucke <luckec@tool-garage.de>                     |
  17. // +----------------------------------------------------------------------+
  18. //
  19. //    $Id: Driver.php,v 1.20 2006/04/03 21:04:46 luckec Exp $s
  20.  
  21. /**
  22.  * uses PEAR_Errorstack
  23.  */
  24. require_once 'PEAR/ErrorStack.php';
  25. require_once 'Date/Holidays/Filter.php';
  26. require_once 'Date/Holidays/Filter/Whitelist.php';
  27. require_once 'Date/Holidays/Filter/Blacklist.php';
  28.  
  29. /**
  30.  * invalid internal name
  31.  *
  32.  * @access  public
  33.  */
  34. define('DATE_HOLIDAYS_INVALID_INTERNAL_NAME'51);
  35.  
  36. /**
  37.  * title for a holiday is not available
  38.  *
  39.  * @access  public
  40.  */
  41. define('DATE_HOLIDAYS_TITLE_UNAVAILABLE'52);
  42.  
  43. /**
  44.  * date could not be converted into a PEAR::Date object
  45.  *
  46.  * date was neither a timestamp nor a string
  47.  *
  48.  * @access  public
  49.  * @deprecated   will certainly be removed
  50.  */
  51. define('DATE_HOLIDAYS_INVALID_DATE'53);
  52.  
  53. /**
  54.  * string that represents a date has wrong format
  55.  *
  56.  * format must be YYYY-MM-DD
  57.  *
  58.  * @access  public
  59.  * @deprecated   will certainly be removed
  60.  */
  61. define('DATE_HOLIDAYS_INVALID_DATE_FORMAT'54);
  62.  
  63. /**
  64.  * date for a holiday is not available
  65.  *
  66.  * @access  public
  67.  */
  68. define('DATE_HOLIDAYS_DATE_UNAVAILABLE'55);
  69.  
  70. /**
  71.  * language-file doesn't exist
  72.  *
  73.  * @access  public
  74.  */
  75. define('DATE_HOLIDAYS_LANGUAGEFILE_NOT_FOUND'56);
  76.  
  77. /**
  78.  * unable to read language-file
  79.  *
  80.  * @access  public
  81.  */
  82. define('DATE_HOLIDAYS_UNABLE_TO_READ_TRANSLATIONDATA'57);
  83.  
  84. /**
  85.  * Name of the static {@link Date_Holidays_Driver} method returning
  86.  * a array of possible ISO3166 codes that identify itself.
  87.  *
  88.  * @access  public
  89.  */
  90. define('DATE_HOLIDAYS_DRIVER_IDENTIFY_ISO3166_METHOD''getISO3166Codes');
  91.  
  92. /**
  93.  * class that helps you to locate holidays for a year
  94.  *
  95.  * @abstract
  96.  * @category    Date
  97.  * @package     Date_Holidays
  98.  * @subpackage  Driver
  99.  * @version     $Id: Driver.php,v 1.20 2006/04/03 21:04:46 luckec Exp $
  100.  * @author      Carsten Lucke <luckec@tool-garage.de>
  101.  */
  102. {
  103.  
  104.    /**
  105.     * locale setting for output
  106.     *
  107.     * @access   protected
  108.     * @var      string 
  109.     */
  110.     var $_locale;
  111.     
  112.    /**
  113.     * locales for which translations of holiday titles are available
  114.     *
  115.     * @access   private
  116.     * @var      array 
  117.     */
  118.     var $_availableLocales = array('C');
  119.     
  120.    /**
  121.     * object's current year
  122.     *
  123.     * @access   protected
  124.     * @var      int 
  125.     */
  126.     var $_year;
  127.     
  128.    /**
  129.     * internal names for the available holidays
  130.     *
  131.     * @access   protected
  132.     * @var      array 
  133.     */
  134.     var $_internalNames = array();
  135.     
  136.    /**
  137.     * dates of the available holidays
  138.     *
  139.     * @access   protected
  140.     * @var      array 
  141.     */
  142.     var $_dates = array();
  143.     
  144.    /**
  145.     * array of the available holidays indexed by date
  146.     *
  147.     * @access   protected
  148.     * @var      array 
  149.     */
  150.     var $_holidays = array();
  151.  
  152.    /**
  153.     * localized names of the available holidays
  154.     *
  155.     * @access   protected
  156.     * @var      array 
  157.     */
  158.     var $_titles = array();
  159.     
  160.    /**
  161.     * Array of holiday-properties indexed by internal-names and furthermore by locales.
  162.     * 
  163.     * <code>
  164.     * $_holidayProperties = array(
  165.     *       'internalName1' =>  array(
  166.     *                               'de_DE' => array(),
  167.     *                               'en_US' => array(),
  168.     *                               'fr_FR' => array()
  169.     *                           )
  170.     *       'internalName2' =>  array(
  171.     *                               'de_DE' => array(),
  172.     *                               'en_US' => array(),
  173.     *                               'fr_FR' => array()
  174.     *                           )
  175.     * );
  176.     * </code>
  177.     */
  178.     var $_holidayProperties = array();
  179.     
  180.    /**
  181.     * Constructor
  182.     *
  183.     * Use the Date_Holidays::factory() method to construct an object of a certain driver
  184.     *
  185.     * @access   protected
  186.     */
  187.     function Date_Holidays_Driver()
  188.     {
  189.     }
  190.     
  191.    /**
  192.     * Method that returns an array containing the ISO3166 codes that may possibly
  193.     * identify a driver.
  194.     * 
  195.     * @static
  196.     * @access public
  197.     * @return array possible ISO3166 codes
  198.     */
  199.     function getISO3166Codes({
  200.         return array();
  201.     }
  202.     
  203.    /**
  204.     * Sets the driver's current year
  205.     *
  206.     * Calling this method forces the object to rebuild the holidays
  207.     *
  208.     * @access   public
  209.     * @param    int     $year   year
  210.     * @return   boolean true on success, otherwise a PEAR_ErrorStack object
  211.     * @throws   object PEAR_ErrorStack
  212.     * @uses     _buildHolidays()
  213.     */
  214.     function setYear($year)
  215.     {
  216.         $this->_year    =   $year;
  217.         return $this->_buildHolidays();
  218.     }
  219.     
  220.    /**
  221.     * Returns the driver's current year
  222.     *
  223.     * @access   public
  224.     * @return   int     current year
  225.     */
  226.     function getYear()
  227.     {
  228.         return $this->_year;
  229.     }
  230.     
  231.    /**
  232.     * Build the internal arrays that contain data about the calculated holidays
  233.     *
  234.     * @abstract
  235.     * @access   protected
  236.     * @return   boolean true on success, otherwise a PEAR_ErrorStack object
  237.     * @throws   object PEAR_ErrorStack
  238.     */
  239.     function _buildHolidays()
  240.     {
  241.     }
  242.     
  243.    /**
  244.     * Add a driver component
  245.     *
  246.     *
  247.     *
  248.     * @abstract
  249.     * @access   public
  250.     * @param    object Date_Holidays_Driver $driver driver-object
  251.     */
  252.     function addDriver($driver)
  253.     {
  254.     }
  255.     
  256.    /**
  257.     * Remove a driver component
  258.     *
  259.     * @abstract
  260.     * @access   public
  261.     * @param    object Date_Holidays_Driver $driver driver-object
  262.     * @return   boolean true on success, otherwise a PEAR_Error object
  263.     * @throws   object PEAR_Error   DATE_HOLIDAYS_DRIVER_NOT_FOUND
  264.     */
  265.     function removeDriver($driver)
  266.     {
  267.     }
  268.     
  269.    /**
  270.     * Returns the internal names of holidays that were calculated
  271.     *
  272.     * @access   public
  273.     * @return   array 
  274.     */
  275.     function getInternalHolidayNames()
  276.     {
  277.         return $this->_internalNames;
  278.     }
  279.     
  280.    /**
  281.     * Returns localized titles of all holidays or those accepted by the filter
  282.     *
  283.     * @access   public
  284.     * @param    Date_Holidays_Filter    filter-object (or an array !DEPRECATED!)
  285.     * @param    string  $locale         locale setting that shall be used by this method
  286.     * @return   array   array with localized holiday titles on success, otherwise a PEAR_Error object
  287.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  288.     * @uses     getHolidayTitle()
  289.     */
  290.     function getHolidayTitles($filter = null$locale = null)
  291.     {
  292.         if (is_null($filter)) {
  293.             $filter = new Date_Holidays_Filter_Blacklist(array());
  294.         elseif (is_array($filter)) {
  295.             $filter = new Date_Holidays_Filter_Whitelist($filter);
  296.         }
  297.         
  298.         $titles =   array();
  299.         
  300.         foreach ($this->_internalNames as $internalName{
  301.             if ($filter->accept($internalName)) {
  302.                 $title $this->getHolidayTitle($internalName$locale);
  303.                 if (Date_Holidays::isError($title)) {
  304.                     return $title;
  305.                 }
  306.                 $titles[$internalName$title;
  307.             }
  308.         }
  309.         
  310.         return $titles;
  311.     }
  312.     
  313.    /**
  314.     * Returns localized title for a holiday
  315.     *
  316.     * @access   public
  317.     * @param    string  $internalName   internal name for holiday
  318.     * @param    string  $locale         locale setting that shall be used by this method
  319.     * @return   string  title on success, otherwise a PEAR_Error object
  320.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME, DATE_HOLIDAYS_TITLE_UNAVAILABLE
  321.     */
  322.     function getHolidayTitle($internalName$locale = null)
  323.     {
  324.         if (in_array($internalName$this->_internalNames)) {
  325.             return Date_Holidays::raiseError(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'Invalid internal name: ' $internalName);
  326.         }
  327.         
  328.         if (is_null($locale)) {
  329.             $locale =   $this->_findBestLocale($this->_locale);
  330.         else {
  331.             $locale =   $this->_findBestLocale($locale);
  332.         }
  333.         
  334.         if (isset($this->_titles[$locale][$internalName])) {
  335.             if (Date_Holidays::staticGetProperty('DIE_ON_MISSING_LOCALE')) {
  336.                 return Date_Holidays::raiseError(DATE_HOLIDAYS_TITLE_UNAVAILABLE'The internal name (' $internalName 
  337.                     ') for the holiday was correct but no localized title could be found');
  338.             }
  339.         }
  340.  
  341.         return isset($this->_titles[$locale][$internalName]
  342.             $this->_titles[$locale][$internalName$this->_titles['C'][$internalName];
  343.     }
  344.     
  345.     
  346.    /**
  347.     * Returns the localized properties of a holiday. If no properties have been stored an empty
  348.     * array will be returned.
  349.     *
  350.     * @access   public
  351.     * @param    string  $internalName   internal name for holiday
  352.     * @param    string  $locale         locale setting that shall be used by this method
  353.     * @return   array   array of properties on success, otherwise a PEAR_Error object
  354.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  355.     */
  356.     function getHolidayProperties($internalName$locale = null)
  357.     {
  358.         if (in_array($internalName$this->_internalNames)) {
  359.             return Date_Holidays::raiseError(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'Invalid internal name: ' $internalName);
  360.         }
  361.         
  362.         if (is_null($locale)) {
  363.             $locale =   $this->_findBestLocale($this->_locale);
  364.         else {
  365.             $locale =   $this->_findBestLocale($locale);
  366.         }
  367.  
  368.         
  369.         $properties = array();
  370.         if (isset($this->_holidayProperties[$internalName][$locale])) {
  371.             $properties $this->_holidayProperties[$internalName][$locale];
  372.         }
  373.         return $properties;
  374.     }
  375.     
  376.     
  377.    /**
  378.     * Returns all holidays that the driver knows.
  379.     *
  380.     * You can limit the holidays by passing a filter, then only those
  381.     * holidays accepted by the filter will be returned.
  382.     *
  383.     * Return format:
  384.     * <pre>
  385.     *   array(
  386.     *       'easter'        =>  object of type Date_Holidays_Holiday,
  387.     *       'eastermonday'  =>  object of type Date_Holidays_Holiday,
  388.     *       ...
  389.     *   )
  390.     * </pre>
  391.     *
  392.     * @access   public
  393.     * @param    Date_Holidays_Filter $filter    filter-object (or an array !DEPRECATED!)
  394.     * @param    string  $locale     locale setting that shall be used by this method
  395.     * @return   array   numeric array containing objects of Date_Holidays_Holiday on success,
  396.     *        otherwise a PEAR_Error object
  397.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  398.     * @see      getHoliday()
  399.     */
  400.     function getHolidays($filter = null$locale = null)
  401.     {
  402.         if (is_null($filter)) {
  403.             $filter = new Date_Holidays_Filter_Blacklist(array());
  404.         elseif (is_array($filter)) {
  405.             $filter = new Date_Holidays_Filter_Whitelist($filter);
  406.         }
  407.         
  408.         if (is_null($locale)) {
  409.             $locale $this->_locale;
  410.         }
  411.         
  412.         $holidays       = array();
  413.         
  414.         foreach ($this->_internalNames as $internalName{
  415.             if ($filter->accept($internalName)) {
  416.                 // no need to check for valid internal-name, will be done by #getHoliday()
  417.                 $holidays[$internalName$this->getHoliday($internalName$locale);
  418.             }
  419.         }
  420.         
  421.         return $holidays;
  422.     }
  423.     
  424.    /**
  425.     * Returns the specified holiday
  426.     *
  427.     * Return format:
  428.     * <pre>
  429.     *   array(
  430.     *       'title' =>  'Easter Sunday'
  431.     *       'date'  =>  '2004-04-11'
  432.     *   )
  433.     * </pre>
  434.     *
  435.     * @access   public
  436.     * @param    string  $internalName   internal name of the holiday
  437.     * @param    string  $locale         locale setting that shall be used by this method
  438.     * @return   object Date_Holidays_Holiday    holiday's information on success, otherwise a PEAR_Error object
  439.     * @throws   object PEAR_Error       DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  440.     * @uses     getHolidayTitle()
  441.     * @uses     getHolidayDate()
  442.     */
  443.     function getHoliday($internalName$locale = null)
  444.     {
  445.         if (in_array($internalName$this->_internalNames)) {
  446.                 'Invalid internal name: ' $internalName);
  447.         }
  448.         if (is_null($locale)) {
  449.             $locale $this->_locale;
  450.         }
  451.         
  452.         $title      $this->getHolidayTitle($internalName$locale);
  453.         if (Date_Holidays::isError($title)) {
  454.             return $title;
  455.         }
  456.         $date       $this->getHolidayDate($internalName);
  457.         if (Date_Holidays::isError($date)) {
  458.             return $date;
  459.         }
  460.         $properties $this->getHolidayProperties($internalName$locale);
  461.         if (Date_Holidays::isError($properties)) {
  462.             return $properties;
  463.         }
  464.         
  465.         $holiday = new Date_Holidays_Holiday($internalName$title$date$properties);
  466.         return $holiday;
  467.     }
  468.     
  469.    /**
  470.     * Determines whether a date represents a holiday or not
  471.     *
  472.     * @access   public
  473.     * @param    mixed   $date       date (can be a timestamp, string or PEAR::Date object)
  474.     * @param    Date_Holidays_Filter $filter    filter-object (or an array !DEPRECATED!)
  475.     * @return   boolean true if date represents a holiday, otherwise false
  476.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_DATE, DATE_HOLIDAYS_INVALID_DATE_FORMAT
  477.     */
  478.     function isHoliday($date$filter = null)
  479.     {
  480.         if (is_a($date'Date')) {
  481.             $date   $this->_convertDate($date);
  482.             if (Date_Holidays::isError($date)) {
  483.                 return $date;
  484.             }
  485.         }
  486.  
  487.         if (is_null($filter)) {
  488.             $filter = new Date_Holidays_Filter_Blacklist(array());
  489.         elseif (is_array($filter)) {
  490.             $filter = new Date_Holidays_Filter_Whitelist($filter);
  491.         }
  492.         
  493.         foreach (array_keys($this->_datesas $internalName{
  494.             if ($filter->accept($internalName)) {
  495.                 if (Date_Holidays_Driver::dateSloppyCompare(
  496.                         $date$this->_dates[$internalName]!= 0{
  497.                     continue;
  498.                 }
  499.                 return true;
  500.             }
  501.         }
  502.         return false;
  503.     }
  504.     
  505.    /**
  506.     * Returns a <code>Date_Holidays_Holiday</code> object, if any was found,
  507.     * matching the specified date.
  508.     *
  509.     * Normally the method will return the object of the first holiday matching the date.
  510.     * If you want the method to continue searching holidays for the specified date,
  511.     * set the 4th param to true.
  512.     *
  513.     * If multiple holidays match your date, the return value will be an array containing a number
  514.     * of <code>Date_Holidays_Holiday</code> items.
  515.     *
  516.     * @access   public
  517.     * @param    mixed   $date       date (timestamp | string | PEAR::Date object)
  518.     * @param    string  $locale     locale setting that shall be used by this method
  519.     * @param    boolean $multiple 
  520.     * @return   object  object of type Date_Holidays_Holiday on success
  521.     *                    (numeric array of those on multiple search),
  522.     *                    if no holiday was found, matching this date, null is returned
  523.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_DATE, DATE_HOLIDAYS_INVALID_DATE_FORMAT
  524.     * @uses     getHoliday()
  525.     * @uses     getHolidayTitle()
  526.     * @see      getHoliday()
  527.     ***/
  528.     function getHolidayForDate($date$locale = null$multiple = false)
  529.     {
  530.         if (!is_a($date'Date')) {
  531.             $date $this->_convertDate($date);
  532.             if (Date_Holidays::isError($date)) {
  533.                 return $date;
  534.             }
  535.         }
  536.         $isodate mktime(000$date->getMonth()$date->getDay()$date->getYear());
  537.         unset($date);
  538.         if (is_null($locale)) {
  539.             $locale $this->_locale;
  540.         }
  541.         if (array_key_exists($isodate$this->_holidays)) {
  542.             if (!$multiple{
  543.                 //get only the first feast for this day
  544.                 $internalName $this->_holidays[$isodate][0];
  545.                 $result $this->getHoliday($internalName$locale);
  546.                 return Date_Holidays::isError($result? null : $result;
  547.             }
  548.             // array that collects data, if multiple searching is done
  549.             $data = array();
  550.             foreach($this->_holidays[$isodateas $internalName{
  551.                 $result $this->getHoliday($internalName$locale);
  552.                 if (Date_Holidays::isError($result)) {
  553.                     continue;
  554.                 }
  555.                 $data[$result;
  556.             }
  557.             return $data;
  558.         }
  559.         return null;
  560.     }
  561.     
  562.    /**
  563.     * Returns an array containing a number of <code>Date_Holidays_Holiday</code> items.
  564.     * 
  565.     * If no items have been found the returned array will be empty.
  566.     * 
  567.     * @access   public
  568.     * @param    mixed   $start  date (timestamp | string | PEAR::Date object)
  569.     * @param    mixed   $end    date (timestamp | string | PEAR::Date object)
  570.     * @param    Date_Holidays_Filter $filter    filter-object (or an array !DEPRECATED!)
  571.     * @param    string  $locale locale setting that shall be used by this method
  572.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_DATE, DATE_HOLIDAYS_INVALID_DATE_FORMAT
  573.     * @return   array   an array containing a number of <code>Date_Holidays_Holiday</code> items
  574.     */
  575.     function getHolidaysForDatespan($start$end$filter = null$locale = null)
  576.     {
  577.         if (is_null($filter)) {
  578.             $filter = new Date_Holidays_Filter_Blacklist(array());
  579.         elseif (is_array($filter)) {
  580.             $filter = new Date_Holidays_Filter_Whitelist($filter);
  581.         }
  582.         
  583.         if (!is_a($start'Date')) {
  584.             $start $this->_convertDate($start);
  585.             if (Date_Holidays::isError($start)) {
  586.                 return $start;
  587.             }
  588.         }
  589.         if (!is_a($end'Date')) {
  590.             $end $this->_convertDate($end);
  591.             if (Date_Holidays::isError($end)) {
  592.                 return $end;
  593.             }
  594.         }
  595.         
  596.         $isodateStart   mktime(000$start->getMonth()$start->getDay()
  597.                 $start->getYear());
  598.         unset($start);
  599.         $isodateEnd     mktime(000$end->getMonth()$end->getDay()$end->getYear());
  600.         unset($end);
  601.         if (is_null($locale)) {
  602.             $locale $this->_locale;
  603.         }
  604.     
  605.         $internalNames = array();
  606.         
  607.         foreach ($this->_holidays as $isoDateTS => $arHolidays{
  608.             if ($isoDateTS >= $isodateStart && $isoDateTS <= $isodateEnd{
  609.                 $internalNames array_merge($internalNames$arHolidays);
  610.             }
  611.         }
  612.         
  613.         $retval = array();
  614.         foreach ($internalNames as $internalName{
  615.             if ($filter->accept($internalName)) {
  616.                 $retval[$this->getHoliday($internalName$locale);
  617.             }
  618.         }
  619.         return $retval;
  620.         
  621.     }
  622.     
  623.    /**
  624.     * Converts timestamp or date-string into da PEAR::Date object
  625.     *
  626.     * @static
  627.     * @access   private
  628.     * @param    mixed   $date   date
  629.     * @return   object PEAR_Date 
  630.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_DATE, DATE_HOLIDAYS_INVALID_DATE_FORMAT
  631.     */
  632.     function _convertDate($date)
  633.     {
  634.         if (is_string($date)) {
  635.             if (preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}/'$date)) {
  636.                 return Date_Holidays::raiseError(DATE_HOLIDAYS_INVALID_DATE_FORMAT
  637.                     'Date-string has wrong format (must be YYYY-MM-DD)');
  638.             }
  639.             $date = new Date($date);
  640.             return $date;
  641.         }
  642.         
  643.         if (is_int($date)) {
  644.             $date = new Date(date('Y-m-d'$date));
  645.             return $date;
  646.         }
  647.         
  648.             'The date you specified is invalid');
  649.     }
  650.     
  651.    /**
  652.     * Adds all holidays in the array to the driver's internal list of holidays.
  653.     * 
  654.     * Format of the array:
  655.     * <pre>
  656.     *   array(
  657.     *       'newYearsDay'   => array(
  658.     *           'date'          => '01-01',
  659.     *           'title'         => 'New Year\'s Day',
  660.     *           'translations'  => array(
  661.     *               'de_DE' =>  'Neujahr',
  662.     *               'en_EN' =>  'New Year\'s Day'
  663.     *           )
  664.     *       ),
  665.     *       'valentinesDay' => array(
  666.     *           ...
  667.     *       )
  668.     *   );
  669.     * </pre>
  670.     * 
  671.     * @access   protected
  672.     * @param    array       $holidays   static holidays' data
  673.     * @uses     _addHoliday()
  674.     */
  675.     function _addStaticHolidays($holidays)
  676.     {
  677.         foreach ($holidays as $internalName => $holiday{
  678.             // add the holiday's basic data
  679.             $this->_addHoliday($internalName$this->_year . '-' $holiday['date']$holiday['title']);
  680.         }
  681.     }
  682.     
  683.    /**
  684.     * Adds a holiday to the driver's holidays
  685.     *
  686.     * @access   protected
  687.     * @param    string  $internalName   internal name - must not contain characters that aren't allowed as variable-names
  688.     * @param    mixed   $date           date (timestamp | string | PEAR::Date object)
  689.     * @param    string  $title          holiday title
  690.     */
  691.     function _addHoliday($internalName$date$title)
  692.     {
  693.         if (is_a($date'Date')) {
  694.             $date   = new Date($date);
  695.         }
  696.         
  697.         $this->_dates[$internalName]        $date;
  698.         $this->_titles['C'][$internalName]  $title;
  699.         $isodate mktime(000$date->getMonth()$date->getDay()$date->getYear());
  700.         if (!isset($this->_holidays[$isodate])) {
  701.             $this->_holidays[$isodate= array();
  702.         }
  703.         array_push($this->_holidays[$isodate]$internalName);
  704.         array_push($this->_internalNames$internalName);
  705.     }
  706.     
  707.    /**
  708.     * Add a localized translation for a holiday's title. Overwrites existing data.
  709.     *
  710.     * @access   protected
  711.     * @param    string  $internalName   internal name of an existing holiday
  712.     * @param    string  $locale         locale setting that shall be used by this method
  713.     * @param    string  $title          title
  714.     * @return   true on success, otherwise a PEAR_Error object
  715.     * @throws   object PEAR_Error       DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  716.     */
  717.     function _addTranslationForHoliday($internalName$locale$title)
  718.     {
  719.         if (in_array($internalName$this->_internalNames)) {
  720.                 'Couldn\'t add translation (' $locale ') for holiday with this internal name: ' $internalName);
  721.         }
  722.         
  723.         if (in_array($locale$this->_availableLocales)) {
  724.             array_push($this->_availableLocales$locale);
  725.         }
  726.         $this->_titles[$locale][$internalName]  $title;
  727.         return true;
  728.     }
  729.     
  730.     
  731.    /**
  732.     * Adds a localized (regrading translation etc.) string-property for a holiday.
  733.     * Overwrites existing data.
  734.     *  
  735.     * @access   public
  736.     * @param    string  internal-name
  737.     * @param    string  locale-setting
  738.     * @param    string  property-identifier
  739.     * @param    mixed   property-value
  740.     * @return   boolean true on success, false otherwise
  741.     * @throws   PEAR_ErrorStack if internal-name does not exist
  742.     */ 
  743.     function _addStringPropertyForHoliday($internalName$locale$propId$propVal
  744.     {
  745.         if (in_array($internalName$this->_internalNames)) {
  746.                 'Couldn\'t add property (locale: ' $locale ') for holiday with this internal name: ' $internalName);
  747.         }
  748.         
  749.         if (!isset($this->_holidayProperties[$internalName]|| 
  750.                 !is_array($this->_holidayProperties[$internalName])) {
  751.  
  752.             $this->_holidayProperties[$internalName= array();
  753.         }
  754.         
  755.         if (isset($this->_holidayProperties[$internalName][$locale]||
  756.                 !is_array($this->_holidayProperties[$internalName][$locale])) {
  757.                     
  758.             $this->_holidayProperties[$internalName][$locale= array();
  759.         }
  760.         
  761.         $this->_holidayProperties[$internalName][$locale][$propId$propVal;
  762.         return true;
  763.     }
  764.     
  765.    /**
  766.     * Adds a arbitrary number of localized string-properties for the specified holiday.
  767.     * 
  768.     * @access   public
  769.     * @param    string  internal-name
  770.     * @param    string  locale-setting
  771.     * @param    array   associative array: array(propId1 => value1, propid2 => value2, ...)
  772.     * @return   boolean true on success, false otherwise
  773.     * @throws   PEAR_ErrorStack if internal-name does not exist
  774.     */
  775.     function _addStringPropertiesForHoliday($internalName$locale$properties
  776.     {        
  777.         foreach ($properties as $propId => $propValue{
  778.             return $this->_addStringPropertyForHoliday($internalName$locale
  779.                    $propId$propValue);
  780.         }
  781.         
  782.         return true;
  783.     }
  784.     
  785.    /**
  786.     * Add a language-file's content
  787.     * 
  788.     * The language-file's content will be parsed and translations, properties, etc. for
  789.     * holidays will be made available with the specified locale.
  790.     * 
  791.     * @access   public
  792.     * @param    string  $file   filename of the language file
  793.     * @param    string  $locale locale-code of the translation
  794.     * @return   boolean true on success, otherwise a PEAR_ErrorStack object
  795.     * @throws   object PEAR_Errorstack
  796.     */
  797.     function addTranslationFile($file$locale)
  798.     {
  799.         if (file_exists($file)) {
  800.                     'Language-file not found: ' $file);
  801.             return Date_Holidays::getErrorStack();
  802.         }
  803.         
  804.         require_once 'XML/Unserializer.php';
  805.         $options = array(
  806.                             'parseAttributes'   =>  false,
  807.                             'attributesArray'   =>  false,
  808.                             'keyAttribute'      => array('property' => 'id'),
  809.                             'forceEnum'      => array('holiday')
  810.                         );
  811.         $unserializer = new XML_Unserializer($options);
  812.     
  813.         // unserialize the document
  814.         $status $unserializer->unserialize($filetrue);    
  815.     
  816.         if (PEAR::isError($status)) {
  817.             return Date_Holidays::raiseError($status->getCode()$status->getMessage());
  818.         
  819.         
  820.         $content $unserializer->getUnserializedData();
  821.         return $this->_addTranslationData($content$locale);
  822.     }
  823.     
  824.    /**
  825.     * Add a compiled language-file's content
  826.     * 
  827.     * The language-file's content will be unserialized and translations, properties, etc. for
  828.     * holidays will be made available with the specified locale.
  829.     * 
  830.     * @access   public
  831.     * @param    string  $file   filename of the compiled language file
  832.     * @param    string  $locale locale-code of the translation
  833.     * @return   boolean true on success, otherwise a PEAR_ErrorStack object
  834.     * @throws   object PEAR_Errorstack
  835.     */
  836.     function addCompiledTranslationFile($file$locale)
  837.     {
  838.         if (file_exists($file)) {
  839.                     'Language-file not found: ' $file);
  840.             return Date_Holidays::getErrorStack();
  841.         }
  842.         
  843.         $content file_get_contents($file);
  844.         if ($content === false{
  845.             return false;
  846.         }
  847.         $data unserialize($content);
  848.         if ($data === false{
  849.                     'Unable to read translation-data - file maybe damaged: ' $file);
  850.         }
  851.         return $this->_addTranslationData($data$locale);
  852.     }
  853.     
  854.    /**
  855.     * Add a language-file's content. Translations, properties, etc. for
  856.     * holidays will be made available with the specified locale.
  857.     * 
  858.     * @access   public
  859.     * @param    array   $data   translated data
  860.     * @param    string  $locale locale-code of the translation
  861.     * @return   boolean true on success, otherwise a PEAR_ErrorStack object
  862.     * @throws   object PEAR_Errorstack
  863.     */
  864.     function _addTranslationData($data$locale)
  865.     {
  866.         foreach ($data['holidays']['holiday'as $holiday{
  867.             $this->_addTranslationForHoliday($holiday['internal-name']$locale
  868.                     $holiday['translation']);
  869.     
  870.             if (isset($holiday['properties']&& is_array($holiday['properties'])) {
  871.                 foreach ($holiday['properties'as $propId => $propVal{
  872.                     $this->_addStringPropertyForHoliday($holiday['internal-name']$locale
  873.                         $propId$propVal);
  874.                 }
  875.             }
  876.             
  877.         }
  878.         
  879.         if (Date_Holidays::errorsOccurred()) {
  880.             return Date_Holidays::getErrorStack();
  881.         }
  882.         
  883.         return true;
  884.     }
  885.     
  886.    /**
  887.     * Remove a holiday from internal storage
  888.     *
  889.     * This method should be used within driver classes to unset holidays that were inherited from
  890.     * parent-drivers
  891.     *
  892.     * @access   protected
  893.     * @param    $string     $internalName   internal name
  894.     * @return   boolean     true on success, otherwise a PEAR_Error object
  895.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  896.     */
  897.     function _removeHoliday($internalName)
  898.     {
  899.         if (in_array($internalName$this->_internalNames)) {
  900.                 'Couldn\'t remove holiday with this internal name: ' $internalName);
  901.         }
  902.         
  903.         if (isset($this->_dates[$internalName])) {
  904.             unset($this->_dates[$internalName]);
  905.         }
  906.         $locales    array_keys($this->_titles);
  907.         foreach ($locales as $locale{
  908.             if (isset($this->_titles[$locale][$internalName])) {
  909.                 unset($this->_titles[$locale][$internalName]);
  910.             }
  911.         }
  912.         $index      array_search($internalName$this->_internalNames);
  913.         if (is_null($index)) {
  914.             unset($this->_internalNames[$index]);
  915.         }
  916.         return true;
  917.     }
  918.     
  919.    /**
  920.     * Finds the best internally available locale for the specified one
  921.     *
  922.     * @access   protected
  923.     * @param    string  $locale locale
  924.     * @return   string  best locale available
  925.     */
  926.     function _findBestLocale($locale)
  927.     {
  928.         /* exact locale is available */
  929.         if (in_array($locale$this->_availableLocales)) {
  930.             return $locale;
  931.         }
  932.         
  933.         /* first two letter are equal */
  934.         foreach ($this->_availableLocales as $aLocale{
  935.             if (strncasecmp($aLocale$locale2== 0{
  936.                 return $aLocale;
  937.             }
  938.         }
  939.         
  940.         /* no appropriate locale available, will use driver's internal locale */
  941.         return 'C';
  942.     }
  943.     
  944.    /**
  945.     * Returns date of a holiday
  946.     *
  947.     * @access   public
  948.     * @param    string  $internalName   internal name for holiday
  949.     * @return   object Date             date of the holiday as PEAR::Date object on success, otherwise a PEAR_Error object
  950.     * @throws   object PEAR_Error       DATE_HOLIDAYS_INVALID_INTERNAL_NAME, DATE_HOLIDAYS_DATE_UNAVAILABLE
  951.     */
  952.     function getHolidayDate($internalName)
  953.     {
  954.         if (in_array($internalName$this->_internalNames)) {
  955.             return Date_Holidays::raiseError(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'Invalid internal name: ' $internalName);
  956.         }
  957.         
  958.         if (isset($this->_dates[$internalName])) {
  959.             return Date_Holidays::raiseError(DATE_HOLIDAYS_DATE_UNAVAILABLE'Date for holiday with internal name ' $internalName 
  960.                 ' is not available');
  961.         }
  962.         
  963.         return $this->_dates[$internalName];
  964.     }
  965.     
  966.    /**
  967.     * Returns dates of all holidays or those accepted by the applied filter.
  968.     *
  969.     * Structure of the returned array:
  970.     * <pre>
  971.     * array(
  972.     *   'internalNameFoo' => object of type date,
  973.     *   'internalNameBar' => object of type date
  974.     * )
  975.     * </pre>
  976.     *
  977.     * @access   public
  978.     * @param    Date_Holidays_Filter    filter-object (or an array !DEPRECATED!)
  979.     * @return   array with holidays' dates on success, otherwise a PEAR_Error object
  980.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  981.     * @uses     getHolidayDate()
  982.     */
  983.     function getHolidayDates($filter = null)
  984.     {
  985.         if (is_null($filter)) {
  986.             $filter = new Date_Holidays_Filter_Blacklist(array());
  987.         elseif (is_array($filter)) {
  988.             $filter = new Date_Holidays_Filter_Whitelist($filter);
  989.         }
  990.         
  991.         $dates = array();
  992.         
  993.         foreach ($this->_internalNames as $internalName{
  994.             if ($filter->accept($internalName)) {
  995.                 $date $this->getHolidayDate($internalName);
  996.                 if (Date_Holidays::isError($date)) {
  997.                     return $date;
  998.                 }
  999.                 $dates[$internalName$this->getHolidayDate($internalName);
  1000.             }
  1001.         }
  1002.         return $dates;
  1003.     }
  1004.     
  1005.    /**
  1006.     * Sets the driver's locale
  1007.     *
  1008.     * @access   public
  1009.     * @param    string  $locale locale
  1010.     */
  1011.     function setLocale($locale)
  1012.     {
  1013.         $this->_locale  =   $locale;
  1014.     }
  1015.     
  1016.    /**
  1017.     * Sloppily compares two date objects (only year, month and day are compared).
  1018.     * Does not take the date's timezone into account.
  1019.     * 
  1020.     * @static
  1021.     * @access private
  1022.     * @param Date $d1 a date object
  1023.     * @param Date $d2 another date object
  1024.     * @return int 0 if the dates are equal, -1 if d1 is before d2, 1 if d1 is after d2
  1025.     * 
  1026.     */
  1027.     function dateSloppyCompare($d1$d2
  1028.     {
  1029.         $d1->setTZ(new Date_TimeZone('UTC'));
  1030.         $d2->setTZ(new Date_TimeZone('UTC'));
  1031.         $days1 = Date_Calc::dateToDays($d1->day$d1->month$d1->year);
  1032.         $days2 = Date_Calc::dateToDays($d2->day$d2->month$d2->year);
  1033.         if ($days1 $days2return -1;
  1034.         if ($days1 $days2return 1;
  1035.         return 0;
  1036.     }
  1037. }
  1038. ?>

Documentation generated on Mon, 11 Mar 2019 15:03:07 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.