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

Documentation generated on Tue, 22 Jan 2013 01:00:06 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.