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

Source for file Composite.php

Documentation is available at Composite.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: Composite.php,v 1.3 2005/02/11 13:30:19 luckec Exp $
  20.  
  21. /**
  22.  * driver not found
  23.  *
  24.  * @access  public
  25.  */
  26. define('DATE_HOLIDAYS_DRIVER_NOT_FOUND'100);
  27.  
  28. /**
  29.  * Composite driver - you can use this one to combine two or more drivers
  30.  *
  31.  * @category    Date
  32.  * @package     Date_Holidays
  33.  * @subpackage  Driver
  34.  * @version     $Id: Composite.php,v 1.3 2005/02/11 13:30:19 luckec Exp $
  35.  * @author      Carsten Lucke <luckec@tool-garage.de>
  36.  */
  37. {
  38.    /**
  39.     * compound of drivers
  40.     *
  41.     * @access   private
  42.     * @var      array 
  43.     */
  44.     var $_drivers = array();
  45.     
  46.    /**
  47.     * Driver-ids ordered by importance
  48.     *
  49.     * @access   private
  50.     * @var      array 
  51.     */
  52.     var $_driverIds = array();
  53.     
  54.    /**
  55.     * Constructor
  56.     *
  57.     * Use the Date_Holidays::factory() method to construct an object of a certain driver
  58.     *
  59.     * @access   protected
  60.     */
  61.     function Date_Holidays_Driver_Composite()
  62.     {
  63.     }
  64.     
  65.    /**
  66.     * Build the internal arrays that contain data about the calculated holidays
  67.     *
  68.     * @access   private
  69.     * @return   boolean true on success, otherwise a PEAR_ErrorStack object
  70.     * @throws   object PEAR_ErrorStack
  71.     */
  72.     function _buildHolidays()
  73.     {
  74.     }
  75.     
  76.    /**
  77.     * Add a driver component
  78.     *
  79.     * @access   public
  80.     * @param    object Date_Holidays_Driver $driver driver-object
  81.     */
  82.     function addDriver($driver)
  83.     {
  84.         $id                     md5(serialize($driver));
  85.         $this->_drivers[$id]    &$driver;
  86.         array_push($this->_driverIds$id);
  87.         
  88.         $this->_internalNames   = array_merge($driver->getInternalHolidayNames()$this->_internalNames);
  89.     }
  90.     
  91.    /**
  92.     * Remove a driver component
  93.     *
  94.     * @access   public
  95.     * @param    object Date_Holidays_Driver $driver driver-object
  96.     * @return   boolean true on success, otherwise a PEAR_Error object
  97.     * @throws   object PEAR_Error   DATE_HOLIDAYS_DRIVER_NOT_FOUND
  98.     */
  99.     function removeDriver($driver)
  100.     {
  101.         $id md5(serialize($driver));
  102.         // unset driver object
  103.         if (isset($this->_drivers[$id])) {
  104.             return Date_Holidays::raiseError(DATE_HOLIDAYS_DRIVER_NOT_FOUND'Driver not found');
  105.         }
  106.         unset($this->_drivers[$id]);
  107.  
  108.         // unset driver's prio
  109.         $index array_search($id$this->_driverIds);
  110.         unset($this->_driverIds[$index]);
  111.         
  112.         // rebuild the internal-names array
  113.         $this->_internalNames = array();
  114.         foreach ($this->_driverIds as $id{
  115.             $this->_internalNames = array_merge($this->_drivers[$id]->_internalNames$this->_internalNames);
  116.         }
  117. //        $this->_internalNames = array_values(array_unique($this->_internalNames));
  118.         
  119.         return true;
  120.     }
  121.     
  122.    /**
  123.     * Returns the specified holiday
  124.     *
  125.     * Return format:
  126.     * <pre>
  127.     *   array(
  128.     *       'title' =>  'Easter Sunday'
  129.     *       'date'  =>  '2004-04-11'
  130.     *   )
  131.     * </pre>
  132.     *
  133.     * @access   public
  134.     * @param    string  $internalName   internal name of the holiday
  135.     * @param    string  $locale         locale setting that shall be used by this method
  136.     * @return   object Date_Holidays_Holiday    holiday's information on success, otherwise a PEAR_Error object
  137.     * @throws   object PEAR_Error       DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  138.     */
  139.     function getHoliday($internalName$locale = null)
  140.     {
  141.         foreach ($this->_driverIds as $id{
  142.             $holiday $this->_drivers[$id]->getHoliday($internalName$locale);
  143.             if (Date_Holidays::isError($holiday)) {
  144.                /**
  145.                 * lets skip this error, perhaps another driver knows this internal-name
  146.                 */
  147.                 continue;
  148.             }
  149.             return $holiday;
  150.         }
  151.         
  152.         return Date_Holidays::raiseError(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'Invalid internal name: ' $internalName);
  153.     }
  154.     
  155.    /**
  156.     * Returns date of a holiday
  157.     *
  158.     * @access   public
  159.     * @param    string  $internalName   internal name for holiday
  160.     * @return   object Date             date of the holiday as PEAR::Date object on success, otherwise a PEAR_Error object
  161.     * @throws   object PEAR_Error       DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  162.     */
  163.     function getHolidayDate($internalName)
  164.     {
  165.         foreach ($this->_driverIds as $id{
  166.             $date $this->_drivers[$id]->getHolidayDate($internalName);
  167.             if (Date_Holidays::isError($date)) {
  168.                /**
  169.                 * lets skip this error, perhaps another driver knows this internal-name
  170.                 */
  171.                 continue;
  172.             }
  173.             return $date;
  174.         }
  175.         
  176.         return Date_Holidays::raiseError(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'Invalid internal name: ' $internalName);
  177.     }
  178.     
  179.    /**
  180.     * Returns dates of all holidays or those accepted by the specified filter.
  181.     *
  182.     * @access   public
  183.     * @param    Date_Holidays_Filter    filter-object (or an array !DEPRECATED!)
  184.     * @return   array   array with holidays' dates on success, otherwise a PEAR_ErrorStack object
  185.     * @throws   object PEAR_ErrorStack   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  186.     */
  187.     function getHolidayDates($filter = null)
  188.     {
  189.         if (is_null($filter)) {
  190.             $filter &new Date_Holidays_Filter_Blacklist(array());
  191.         elseif (is_array($filter)) {
  192.             $filter &new Date_Holidays_Filter_Whitelist($filter);
  193.         }
  194.  
  195.         $errorStack &Date_Holidays::getErrorStack();
  196.         $dates      = array();
  197.         $notFound   = array();
  198.         
  199.         foreach ($this->_internalNames as $internalName{
  200.             // check if the filter permits further processing
  201.             if ($filter->accept($internalName)) {
  202.                 continue;
  203.             }
  204.             
  205.             foreach ($this->_driverIds as $id{
  206.                 $date &$this->_drivers[$id]->getHolidayDate($internalName);
  207.                 if (Date_Holidays::isError($date)) {
  208.                     if ($date->getCode(== DATE_HOLIDAYS_DATE_UNAVAILABLE{
  209.                        /**
  210.                         * this means a fatal error (would be the right place for sth. like an assert, 
  211.                         * as this should normally never happen)
  212.                         */
  213.                         $errorStack->push(DATE_HOLIDAYS_DATE_UNAVAILABLE'error'array()
  214.                             'No date found for holiday with internal name: ' $internalNamefalsedebug_backtrace());
  215.                         continue;
  216.                     }
  217.                     
  218.                    /**
  219.                     * current driver doesn't have this internalName, trying next driver
  220.                     */
  221.                     array_push($notFound$internalName);
  222.                     continue;
  223.                 }
  224.                /**
  225.                 * internal name found in highest priorized driver, stepping to next internal name
  226.                 * checks if internal name is existent in $notFound array and unsets this entry as it has been found now
  227.                 */
  228.                 $notFound array_unique($notFound);
  229.                 if (in_array($internalName$notFound)) {
  230.                     unset($notFound[array_search($internalName$notFound)]);
  231.                 }
  232.                 $dates[$internalName]   &$date;
  233.                 continue 2;
  234.             }
  235.         }
  236.         
  237.         if (empty($notFound)) {
  238.             foreach ($notFound as $internalName{
  239.                 $errorStack->push(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'error'array()
  240.                     'Invalid internal name: ' $internalNamefalsedebug_backtrace());
  241.             }
  242.         }
  243.         
  244.         if ($errorStack->hasErrors(&& empty($notFound)) {
  245.             return $errorStack;
  246.         }
  247.         return $dates;
  248.     }
  249.     
  250.    /**
  251.     * Returns the title of the holiday, if any was found, matching the specified date.
  252.     *
  253.     * Normally the method will return the title/data for the first holiday matching the date.
  254.     * If you want the mthod to continue searching holidays for the specified date, set the 4th param to true
  255.     * If multiple holidays match your date, the return value will be an array of the titles/data.
  256.     * <pre>
  257.     * array(
  258.     *   array(
  259.     *       'title' => 'New Year',
  260.     *       'date'  => Object of type Date
  261.     *   ),
  262.     *   array(
  263.     *       'title' => 'Circumcision of Jesus',
  264.     *       'date'  => Object of type Date
  265.     *   )
  266.     * )
  267.     * </pre>
  268.     *
  269.     * @access   public
  270.     * @param    mixed   $date       date (timestamp | string | PEAR::Date object)
  271.     * @param    string  $locale     locale setting that shall be used by this method
  272.     * @param    boolean $multiple 
  273.     * @return   object  object of type Date_Holidays_Holiday on success (numeric array of those on multiple search); if no holiday was found, matching this date, null is returned
  274.     * @uses     getHoliday()
  275.     * @uses     getHolidayTitle()
  276.     * @see      getHoliday()
  277.     ***/
  278.     function getHolidayForDate($date$locale = null$multiple = false)
  279.     {
  280.         $holidays = array();
  281.         foreach ($this->_driverIds as $id{
  282.             $holiday &$this->_drivers[$id]->getHolidayForDate($date$locale$multiple);
  283.             if (is_null($holiday)) {
  284.                /**
  285.                 * No holiday found for this date in the current driver, trying next one
  286.                 */
  287.                 continue;
  288.             }
  289.             
  290.             if (is_array($holiday)) {
  291.                 for ($i = 0; $i count($holiday)$i++{
  292.                     $holidays[&$holiday[$i];
  293.                 }
  294.             else {
  295.                 $holidays[]     &$holiday;
  296.             }
  297.             
  298.             if ($multiple{
  299.                 return $holiday;
  300.             }
  301.         }
  302.         
  303.         if (empty($holidays)) {
  304.             return null;
  305.         }
  306.         return $holidays;
  307.     }
  308.     
  309.    /**
  310.     * Returns all holidays that were found
  311.     *
  312.     * Return format:
  313.     * <pre>
  314.     *   array(
  315.     *       'easter' =>  array(
  316.     *           'title' =>  'Easter Sunday'
  317.     *           'date'  =>  '2004-04-11'
  318.     *       ),
  319.     *       'eastermonday'  =>  array(
  320.     *           'title' =>  'Easter Monday'
  321.     *           'date'  =>  '2004-04-12'
  322.     *       ),
  323.     *       ...
  324.     *   )
  325.     * </pre>
  326.     *
  327.     * @access   public
  328.     * @param    Date_Holidays_Filter    filter-object (or an array !DEPRECATED!)
  329.     * @return   array   numeric array containing objects of Date_Holidays_Holiday on success, otherwise a PEAR_ErrorStack object
  330.     * @throws   object PEAR_ErrorStack   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  331.     */
  332.     function getHolidays($filter = null)
  333.     {
  334.         if (is_null($filter)) {
  335.             $filter &new Date_Holidays_Filter_Blacklist(array());
  336.         elseif (is_array($filter)) {
  337.             $filter &new Date_Holidays_Filter_Whitelist($filter);
  338.         }
  339.  
  340.         $errorStack &Date_Holidays::getErrorStack();
  341.         $holidays   = array();
  342.         $notFound   = array();
  343.         
  344.         foreach ($this->_internalNames as $internalName{
  345.             // check if the filter permits further processing
  346.             if ($filter->accept($internalName)) {
  347.                 continue;
  348.             }
  349.             
  350.             foreach ($this->_driverIds as $id{
  351.                 $holiday &$this->_drivers[$id]->getHoliday($internalName);
  352.                 if (Date_Holidays::isError($holiday)) {
  353.                    /**
  354.                     * current driver doesn't have this internalName, trying next driver
  355.                     */
  356.                     array_push($notFound$internalName);
  357.                     continue;
  358.                 }
  359.                /**
  360.                 * internal name found in highest priorized driver, stepping to next internal name
  361.                 * checks if internal name is existent in $notFound array and unsets this entry as it has been found now
  362.                 */
  363.                 $notFound array_unique($notFound);
  364.                 if (in_array($internalName$notFound)) {
  365.                     unset($notFound[array_search($internalName$notFound)]);
  366.                 }
  367.                 $holidays[$internalName&$holiday;
  368.                 continue 2;
  369.             }
  370.         }
  371.         
  372.         if (empty($notFound)) {
  373.             foreach ($notFound as $internalName{
  374.                 $errorStack->push(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'error'array()
  375.                     'Invalid internal name: ' $internalNamefalsedebug_backtrace());
  376.             }
  377.         }
  378.         
  379.         if ($errorStack->hasErrors(&& empty($notFound)) {
  380.             return $errorStack;
  381.         }
  382.         return $holidays;
  383.     }
  384.     
  385.    /**
  386.     * Returns localized title for a holiday
  387.     *
  388.     * @access   public
  389.     * @param    string  $internalName   internal name for holiday
  390.     * @param    string  $locale         locale setting that shall be used by this method
  391.     * @return   string  title on success, otherwise a PEAR_Error object
  392.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME, DATE_HOLIDAYS_TITLE_UNAVAILABLE
  393.     */
  394.     function getHolidayTitle($internalName$locale = null)
  395.     {
  396.         foreach ($this->_driverIds as $id{
  397.             $title $this->_drivers[$id]->getHolidayTitle($internalName$locale);
  398.             if (Date_Holidays::isError($title)) {
  399.                /**
  400.                 * lets skip this error, perhaps another driver knows this internal-name
  401.                 */
  402.                 continue;
  403.             }
  404.             return $title;
  405.         }
  406.         
  407.         return Date_Holidays::raiseError(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'Invalid internal name: ' $internalName);
  408.     }
  409.     
  410.    /**
  411.     * Returns localized titles of all holidays or those specififed in $restrict array
  412.     *
  413.     * @access   public
  414.     * @param    Date_Holidays_Filter    filter-object (or an array !DEPRECATED!)
  415.     * @param    string  $locale     locale setting that shall be used by this method
  416.     * @return   array   array with localized holiday titles on success, otherwise a PEAR_Error object
  417.     * @throws   object PEAR_Error   DATE_HOLIDAYS_INVALID_INTERNAL_NAME
  418.     */
  419.     function getHolidayTitles($filter = null$locale = null)
  420.     {
  421.         if (is_null($filter)) {
  422.             $filter &new Date_Holidays_Filter_Blacklist(array());
  423.         elseif (is_array($filter)) {
  424.             $filter &new Date_Holidays_Filter_Whitelist($filter);
  425.         }
  426.  
  427.         $errorStack &Date_Holidays::getErrorStack();
  428.         $titles     = array();
  429.         $notFound   = array();
  430.         
  431.         foreach ($this->_internalNames as $internalName{
  432.             // check if the filter permits further processing
  433.             if ($filter->accept($internalName)) {
  434.                 continue;
  435.             }
  436.             
  437.             foreach ($this->_driverIds as $id{
  438.                 $title $this->_drivers[$id]->getHolidayTitle($internalName$locale);
  439.                 if (Date_Holidays::isError($title)) {
  440.                    /**
  441.                     * current driver doesn't have this internalName, trying next driver
  442.                     */
  443.                     array_push($notFound$internalName);
  444.                     continue;
  445.                 }
  446.                /**
  447.                 * internal name found in highest priorized driver, stepping to next internal name
  448.                 * checks if internal name is existent in $notFound array and unsets this entry as it has been found now
  449.                 */
  450.                 $notFound array_unique($notFound);
  451.                 if (in_array($internalName$notFound)) {
  452.                     unset($notFound[array_search($internalName$notFound)]);
  453.                 }
  454.                 $titles[$internalName]   $title;
  455.                 continue 2;
  456.             }
  457.         }
  458.         
  459.         if (empty($notFound)) {
  460.             foreach ($notFound as $internalName{
  461.                 $errorStack->push(DATE_HOLIDAYS_INVALID_INTERNAL_NAME'error'array()
  462.                     'Invalid internal name: ' $internalNamefalsedebug_backtrace());
  463.             }
  464.         }
  465.         
  466.         if ($errorStack->hasErrors(&& empty($notFound)) {
  467.             return $errorStack;
  468.         }
  469.         return $titles;
  470.     }
  471.     
  472.    /**
  473.     * Using this method doesn't affect anything. If you have been able to add your driver to this compound,
  474.     * you should also be able to directly execute this action.
  475.     * This method is only available to keep abstraction working.
  476.     *
  477.     * @access   public
  478.     */
  479.     function getYear()
  480.     {
  481.     }
  482.     
  483.    /**
  484.     * This (re)sets the year of every driver-object in the compound.
  485.     * 
  486.     * Note that this will cause every attached driver to recalculate the holidays!
  487.     * 
  488.     * @access   public
  489.     * @param    int     year
  490.     * @return   boolean true on success, otherwise a PEAR_ErrorStack object
  491.     * @throws   object PEAR_ErrorStack
  492.     */
  493.     function setYear($year)
  494.     {
  495.         $errors = false;
  496.         
  497.         foreach ($this->_driverIds as $id{
  498.             if ($this->_drivers[$id]->setYear($year!= true{
  499.                 $errors = true;
  500.             }
  501.         }
  502.         
  503.         if ($errors{
  504.             return Date_Holidays::getErrorStack();
  505.         }
  506.         return true;
  507.     }
  508.     
  509.    /**
  510.     * Determines whether a date represents a holiday or not.
  511.     *
  512.     * The method searches all added drivers for this date, to determine whether it's a holiday.
  513.     *
  514.     * @access   public
  515.     * @param    mixed   $date   date (can be a timestamp, string or PEAR::Date object)
  516.     * @return   boolean true if date represents a holiday, otherwise false
  517.     */
  518.     function isHoliday($date)
  519.     {
  520.         foreach ($this->_driverIds as $id{
  521.             if ($this->_drivers[$id]->isHoliday($date)) {
  522.                 return true;
  523.             }
  524.             continue;
  525.         }
  526.         
  527.         return false;
  528.     }
  529.     
  530.    /**
  531.     * Using this method doesn't affect anything. If you have bben able to add your driver to this compound,
  532.     * you should also be able to directly execute this action.
  533.     * This method is only available to keep abstraction working.
  534.     *
  535.     * @access   public
  536.     */
  537.     function setLocale($locale)
  538.     {
  539.     }
  540. }
  541. ?>

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