├── .gitignore
├── .travis.yml
├── tests
├── BmCalendarTests
│ ├── State
│ │ ├── MockStateA.php
│ │ └── MockStateB.php
│ ├── AbstractDayStateTest.php
│ ├── YearTest.php
│ ├── MonthTest.php
│ ├── DayTest.php
│ ├── Renderer
│ │ └── HtmlCalendarTest.php
│ ├── View
│ │ └── Helper
│ │ │ └── CalendarTest.php
│ └── CalendarTest.php
└── Bootstrap.php
├── src
└── BmCalendar
│ ├── Exception
│ ├── DomainException.php
│ ├── ExceptionInterface.php
│ ├── OutOfRangeException.php
│ └── InvalidArgumentException.php
│ ├── State
│ ├── DayStateInterface.php
│ └── AbstractDayState.php
│ ├── DayProviderInterface.php
│ ├── Renderer
│ ├── CalendarRendererInterface.php
│ └── HtmlCalendar.php
│ ├── Year.php
│ ├── DayInterface.php
│ ├── Month.php
│ ├── Day.php
│ ├── Calendar.php
│ └── View
│ └── Helper
│ └── Calendar.php
├── phpunit.xml.dist
├── composer.json
├── LICENSE.txt
├── .travis
└── travis_build.sh
├── Module.php
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 | composer.lock
3 | clover.xml
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.3
5 | - 5.4
6 |
7 | before_script:
8 | - composer self-update
9 | - composer install --dev --prefer-source
10 | - mkdir -p build/logs
11 |
12 | script: .travis/travis_build.sh
13 |
14 | after_script:
15 | - php vendor/bin/coveralls -v
16 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/State/MockStateA.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | class DomainException extends \DomainException implements ExceptionInterface
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/src/BmCalendar/Exception/ExceptionInterface.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | interface ExceptionInterface
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/src/BmCalendar/Exception/OutOfRangeException.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | class OutOfRangeException extends \OutOfRangeException implements
17 | ExceptionInterface
18 | {
19 | }
20 |
--------------------------------------------------------------------------------
/src/BmCalendar/Exception/InvalidArgumentException.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | class InvalidArgumentException extends \InvalidArgumentException implements
17 | ExceptionInterface
18 | {
19 | }
20 |
--------------------------------------------------------------------------------
/src/BmCalendar/State/DayStateInterface.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | interface DayStateInterface
17 | {
18 | /**
19 | * A unique identifier for grouping related states together.
20 | *
21 | * @return string
22 | */
23 | public static function type();
24 | }
25 |
--------------------------------------------------------------------------------
/src/BmCalendar/State/AbstractDayState.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | abstract class AbstractDayState implements DayStateInterface
17 | {
18 | /**
19 | * Return the name of the class as the type of the DayState class.
20 | *
21 | * @return string
22 | */
23 | public static function type()
24 | {
25 | return get_called_class();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/BmCalendar/DayProviderInterface.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | interface DayProviderInterface
17 | {
18 | /**
19 | * Use this to create and set the state of the provided Day.
20 | *
21 | * @param Month $month
22 | * @param int $dayOfMonth
23 | * @return DayInterface
24 | */
25 | public function createDay(Month $month, $dayOfMonth);
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Bootstrap.php:
--------------------------------------------------------------------------------
1 | add('BmCalendarTests\\', __DIR__);
27 |
28 | unset($files, $file, $loader);
29 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 | ./tests
16 |
17 |
18 |
19 | ./src
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sclinternet/bm-calendar",
3 | "description": "Calendar module which provide the ability to block off days.",
4 | "type": "library",
5 | "license": "MIT",
6 | "homepage": "https://github.com/SCLInternet/SclZfUtilities",
7 | "authors": [
8 | {
9 | "name": "Tom Oram",
10 | "email": "tom@scl.co.uk",
11 | "homepage": "http://github.com/tomphp"
12 | }
13 | ],
14 | "require": {
15 | "php": ">=5.3.3",
16 | "zendframework/zendframework": "2.*"
17 | },
18 | "require-dev": {
19 | "phpunit/phpunit" : "3.7.*",
20 | "squizlabs/php_codesniffer" : "1.*",
21 | "phpmd/phpmd" : "1.4.0",
22 | "satooshi/php-coveralls": "dev-master"
23 | },
24 | "autoload": {
25 | "psr-0": {
26 | "BmCalendar": "src/"
27 | },
28 | "classmap": [
29 | "./Module.php"
30 | ]
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/AbstractDayStateTest.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class AbstractDayStateTest extends \PHPUnit_Framework_TestCase
19 | {
20 | /**
21 | * Make sure type returns the FQCN of the extending class.
22 | *
23 | * @covers BmCalendar\State\AbstractDayState::type
24 | *
25 | * @return void
26 | */
27 | public function testType()
28 | {
29 | $this->assertEquals(
30 | MockStateA::type(),
31 | 'BmCalendarTests\State\MockStateA'
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 SCL Internet (Shireglobe Computers Ltd.)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/src/BmCalendar/Renderer/CalendarRendererInterface.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | interface CalendarRendererInterface
19 | {
20 | /**
21 | * Set the calendar to be renderer.
22 | *
23 | * @param Calendar $calendar
24 | * @return self
25 | */
26 | public function setCalendar(Calendar $calendar);
27 |
28 | /**
29 | * Set which day to display as the starting day of the week.
30 | *
31 | * @param int $startDay
32 | * @return self
33 | */
34 | public function setStartDay($day);
35 |
36 | /**
37 | * Render a month table.
38 | *
39 | * @param int $yearNo
40 | * @param int $monthNo
41 | * @return string
42 | */
43 | public function renderMonth($year, $month);
44 | }
45 |
--------------------------------------------------------------------------------
/.travis/travis_build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ### Run unit tests
4 | vendor/bin/phpunit
5 | PHPUNIT=$?
6 |
7 | ### Check coding standards
8 | vendor/bin/phpcs --standard=psr2 src
9 | PHPCS=$?
10 |
11 | ### Check code quality
12 | #vendor/bin/phpmd src text codesize
13 | #PHPMD=$?
14 |
15 | ### Check for license headers
16 | LICENSE=0
17 |
18 | LICENSE_HEADER="
15 | */
16 | class Year
17 | {
18 | /**
19 | * The year this class represents.
20 | *
21 | * @var int
22 | */
23 | protected $year;
24 |
25 | /**
26 | * __construct
27 | *
28 | * @param int $year
29 | * @return void
30 | */
31 | public function __construct($year)
32 | {
33 | $this->year = (int) $year;
34 | }
35 |
36 | /**
37 | * Checks if this year is a leap year.
38 | *
39 | * @return bool
40 | */
41 | public function isLeap()
42 | {
43 | if (0 !== $this->year % 4) {
44 | return false;
45 | }
46 |
47 | if (0 !== $this->year % 100) {
48 | return true;
49 | }
50 |
51 | if (0 !== $this->year % 400) {
52 | return false;
53 | }
54 |
55 | return true;
56 | }
57 |
58 | /**
59 | * Return the year number.
60 | *
61 | * @return int
62 | */
63 | public function value()
64 | {
65 | return $this->year;
66 | }
67 |
68 | /**
69 | * Convert the year number to a string.
70 | *
71 | * @return string
72 | */
73 | public function __toString()
74 | {
75 | return (string) $this->year;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Module.php:
--------------------------------------------------------------------------------
1 |
21 | */
22 | class Module implements
23 | AutoloaderProviderInterface,
24 | ViewHelperProviderInterface
25 | {
26 | /**
27 | * {@inheritDoc}
28 | *
29 | * @return array
30 | */
31 | public function getAutoloaderConfig()
32 | {
33 | return array(
34 | 'Zend\Loader\StandardAutoloader' => array(
35 | 'namespaces' => array(
36 | __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
37 | ),
38 | ),
39 | );
40 | }
41 |
42 |
43 | /**
44 | * {@inheritDoc}
45 | *
46 | * @return array
47 | */
48 | public function getViewHelperConfig()
49 | {
50 | return array(
51 | 'factories' => array(
52 | 'calendar' => function ($vhm) {
53 | $helper = new \BmCalendar\View\Helper\Calendar();
54 |
55 | $helper->setRenderer(new \BmCalendar\Renderer\HtmlCalendar());
56 |
57 | return $helper;
58 | }
59 | ),
60 | );
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/YearTest.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class YearTest extends \PHPUnit_Framework_TestCase
19 | {
20 | /**
21 | * Test getting the values back from a Year object.
22 | *
23 | * @covers BmCalendar\Year::__construct
24 | * @covers BmCalendar\Year::value
25 | * @covers BmCalendar\Year::__toString
26 | *
27 | * @return void
28 | */
29 | public function testValue()
30 | {
31 | $year = new Year(2053);
32 |
33 | $this->assertEquals(2053, $year->value(), 'The value of the year is incorrect.');
34 |
35 | $this->assertEquals('2053', (string) $year, 'String representation of the year is wrong.');
36 | }
37 |
38 | /**
39 | * Test the is leap function.
40 | *
41 | * @covers BmCalendar\Year::isLeap
42 | *
43 | * @return void
44 | */
45 | public function testIsLeap()
46 | {
47 | $year = new Year(1700);
48 | $this->assertFalse($year->isLeap(), '1700 was not a leap year.');
49 |
50 | $year = new Year(2000);
51 | $this->assertTrue($year->isLeap(), '2000 was a leap year.');
52 |
53 | $year = new Year(2004);
54 | $this->assertTrue($year->isLeap(), '2004 was a leap year.');
55 |
56 | $year = new Year(2002);
57 | $this->assertFalse($year->isLeap(), '2002 was not a leap year.');
58 |
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/BmCalendar/DayInterface.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | interface DayInterface
19 | {
20 | const MONDAY = 1;
21 | const TUESDAY = 2;
22 | const WEDNESDAY = 3;
23 | const THURSDAY = 4;
24 | const FRIDAY = 5;
25 | const SATURDAY = 6;
26 | const SUNDAY = 7;
27 |
28 | /**
29 | * __construct
30 | *
31 | * @param int $day
32 | * @param Month $month
33 | */
34 | public function __construct(Month $month, $day);
35 |
36 | /**
37 | * Return a specific state by type.
38 | *
39 | * @param string $type
40 | * @return DayStateInterface|null NULL if the date doesn't have a state with the request type.
41 | */
42 | public function getState($type);
43 |
44 | /**
45 | * Returns a list of states for this day.
46 | *
47 | * @return DayStateInterface[]
48 | */
49 | public function getStates();
50 |
51 | /**
52 | * Gets the value of action
53 | *
54 | * @return string
55 | */
56 | public function getAction();
57 |
58 | /**
59 | * Returns the month this day belongs to.
60 | *
61 | * @return Month
62 | */
63 | public function getMonth();
64 |
65 | /**
66 | * Returns the day of the week.
67 | *
68 | * @return int
69 | */
70 | public function dayOfWeek();
71 |
72 | /**
73 | * Return the day number.
74 | *
75 | * @return int
76 | */
77 | public function value();
78 |
79 | /**
80 | * Convert the day number to a string.
81 | *
82 | * @return string
83 | */
84 | public function __toString();
85 | }
86 |
--------------------------------------------------------------------------------
/src/BmCalendar/Month.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class Month
19 | {
20 | const JANUARY = 1;
21 | const FEBRURY = 2;
22 | const MARCH = 3;
23 | const APRIL = 4;
24 | const MAY = 5;
25 | const JUNE = 6;
26 | const JULY = 7;
27 | const AUGUST = 8;
28 | const SEPTEMBER = 9;
29 | const OCTOBER = 10;
30 | const NOVEMBER = 11;
31 | const DECEMBER = 12;
32 |
33 | /**
34 | * The month this represents.
35 | *
36 | * @var int
37 | */
38 | protected $month;
39 |
40 | /**
41 | * The year this month is from.
42 | *
43 | * @var Year
44 | */
45 | protected $year;
46 |
47 | /**
48 | * __construct
49 | *
50 | * @param Year $year
51 | * @param int $month
52 | * @throws DomainException
53 | */
54 | public function __construct(Year $year, $month)
55 | {
56 | $month = (int) $month;
57 |
58 | if ($month < 1 || $month > 12) {
59 | throw new DomainException('$month must be between 1 and 12; got "' . $month .'"');
60 | }
61 |
62 | $this->month = $month;
63 | $this->year = $year;
64 | }
65 |
66 | /**
67 | * Gets the number of days in this month.
68 | *
69 | * @return int
70 | */
71 | public function numberOfDays()
72 | {
73 | if (self::APRIL === $this->month
74 | || self::JUNE === $this->month
75 | || self::SEPTEMBER === $this->month
76 | || self::NOVEMBER === $this->month
77 | ) {
78 | return 30;
79 | }
80 |
81 | if (self::FEBRURY === $this->month) {
82 | return $this->year->isLeap() ? 29 : 28;
83 | }
84 |
85 | return 31;
86 | }
87 |
88 | /**
89 | * Returns the day of the week that the 1st of this month is on.
90 | *
91 | * @return int
92 | */
93 | public function startDay()
94 | {
95 | $dateString = sprintf('%04d-%02d-01', $this->year->value(), $this->month);
96 |
97 | $datetime = new \DateTime($dateString);
98 |
99 | return (int) $datetime->format('N');
100 | }
101 |
102 | /**
103 | * Returns the year object that this month belongs to.
104 | *
105 | * @return void
106 | */
107 | public function getYear()
108 | {
109 | return $this->year;
110 | }
111 |
112 | /**
113 | * Return the month number.
114 | *
115 | * @return int
116 | */
117 | public function value()
118 | {
119 | return $this->month;
120 | }
121 |
122 | /**
123 | * Convert the month number to a string.
124 | *
125 | * @return string
126 | */
127 | public function __toString()
128 | {
129 | return (string) $this->month;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/BmCalendar/Day.php:
--------------------------------------------------------------------------------
1 |
18 | */
19 | class Day implements DayInterface
20 | {
21 | /**
22 | * The day this class represents.
23 | *
24 | * @var int
25 | */
26 | protected $day;
27 |
28 | /**
29 | * The month this day belongs to.
30 | *
31 | * @var Month
32 | */
33 | protected $month;
34 |
35 | /**
36 | * The states this day is in.
37 | *
38 | * @var DayStateInterface[]
39 | */
40 | protected $states = array();
41 |
42 | /**
43 | * The URL to go to if this day is clicked
44 | *
45 | * @var string
46 | */
47 | protected $action;
48 |
49 | /**
50 | * {@inheritDoc}
51 | *
52 | * @param int $day
53 | * @param Month $month
54 | */
55 | public function __construct(Month $month, $day)
56 | {
57 | $day = (int) $day;
58 |
59 | if ($day < 1 || $day > $month->numberOfDays()) {
60 | throw new OutOfRangeException('$day value of "' . $day . '" is out of range.');
61 | }
62 |
63 | $this->day = $day;
64 | $this->month = $month;
65 | }
66 |
67 | /**
68 | * Add a state to this day.
69 | *
70 | * @param DayStateInterface $state
71 | * @return self
72 | */
73 | public function addState(DayStateInterface $state)
74 | {
75 | $this->states[$state::type()] = $state;
76 |
77 | return $this;
78 | }
79 |
80 | /**
81 | * {@inheritDoc}
82 | *
83 | * @param string $type
84 | * @return DayStateInterface|null NULL if the date doesn't have a state with the request type.
85 | */
86 | public function getState($type)
87 | {
88 | if (!isset($this->states[$type])) {
89 | return null;
90 | }
91 |
92 | return $this->states[$type];
93 | }
94 |
95 | /**
96 | * {@inheritDoc}
97 | *
98 | * @return DayStateInterface[]
99 | */
100 | public function getStates()
101 | {
102 | return $this->states;
103 | }
104 |
105 | /**
106 | * Sets the value of action
107 | *
108 | * @param string $action
109 | * @return self
110 | */
111 | public function setAction($action)
112 | {
113 | $this->action = (string) $action;
114 | return $this;
115 | }
116 |
117 | /**
118 | * {@inheritDoc}
119 | *
120 | * @return string
121 | */
122 | public function getAction()
123 | {
124 | return $this->action;
125 | }
126 |
127 | /**
128 | * {@inheritDoc}
129 | *
130 | * @return Month
131 | */
132 | public function getMonth()
133 | {
134 | return $this->month;
135 | }
136 |
137 | /**
138 | * {@inheritDoc}
139 | *
140 | * @return int
141 | */
142 | public function dayOfWeek()
143 | {
144 | $dateString = sprintf(
145 | '%04d-%02d-%02d',
146 | $this->month->getYear()->value(),
147 | $this->month->value(),
148 | $this->day
149 | );
150 |
151 | $datetime = new \DateTime($dateString);
152 |
153 | return (int) $datetime->format('N');
154 | }
155 |
156 | /**
157 | * {@inheritDoc}
158 | *
159 | * @return int
160 | */
161 | public function value()
162 | {
163 | return $this->day;
164 | }
165 |
166 | /**
167 | * {@inheritDoc}
168 | *
169 | * @return string
170 | */
171 | public function __toString()
172 | {
173 | return (string) $this->day;
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/MonthTest.php:
--------------------------------------------------------------------------------
1 |
19 | */
20 | class MonthTest extends \PHPUnit_Framework_TestCase
21 | {
22 | /**
23 | * Give a valid Year and an invalid Month
24 | * Which a Month object is created
25 | * Then throw a DomainException
26 | *
27 | * @covers BmCalendar\Month::__construct
28 | * @expectedException BmCalendar\Exception\DomainException
29 | *
30 | * @return void
31 | */
32 | public function testInvalidMonth()
33 | {
34 | $year = new Year(2013);
35 | $month = new Month($year, 15);
36 | }
37 |
38 | /**
39 | * Test getting the values back from a Month object.
40 | *
41 | * @covers BmCalendar\Month::__construct
42 | * @covers BmCalendar\Month::value
43 | * @covers BmCalendar\Month::__toString
44 | *
45 | * @return void
46 | */
47 | public function testValue()
48 | {
49 | $year = new Year(2015);
50 | $month = new Month($year, 5);
51 |
52 | $this->assertEquals($year, $month->getYear(), 'Year objects don\'t match.');
53 |
54 | $this->assertEquals(5, $month->value(), 'Month value is incorrect.');
55 |
56 | $this->assertEquals('5', (string) $month, 'String representation of month is incorrect.');
57 | }
58 |
59 | /**
60 | * Test getting the values back from a Month object.
61 | *
62 | * @covers BmCalendar\Month::__construct
63 | * @covers BmCalendar\Month::getYear
64 | *
65 | * @return void
66 | */
67 | public function testGetYear()
68 | {
69 | $year = new Year(2015);
70 | $month = new Month($year, 5);
71 |
72 | $this->assertEquals($year, $month->getYear(), 'The year object returned is incorrect.');
73 | }
74 |
75 | /**
76 | * testGetNumberOfDays
77 | *
78 | * @dataProvider numberOfDaysProvider
79 | * @covers BmCalendar\Month::numberOfDays
80 | *
81 | * @param int $yearNo
82 | * @param int $monthNo
83 | * @param int $noDays
84 | * @return void
85 | */
86 | public function testNumberOfDays($yearNo, $monthNo, $noDays)
87 | {
88 | // Non-leap year
89 | $year = new Year($yearNo);
90 |
91 | $month = new Month($year, $monthNo);
92 |
93 | $this->assertEquals($noDays, $month->numberOfDays(), "Number of days for $yearNo-$monthNo is incorrect.");
94 | }
95 |
96 | /**
97 | * Test startDay method.
98 | *
99 | * @covers BmCalendar\Month::startDay
100 | *
101 | * @return void
102 | */
103 | public function testStartDay()
104 | {
105 | $month = new Month(new Year(2013), 5);
106 |
107 | $this->assertEquals(Day::WEDNESDAY, $month->startDay(), 'The starting day of the month is wrong.');
108 | }
109 |
110 | /**
111 | * Data provider for numver of days in a month.
112 | *
113 | * @return array
114 | */
115 | public function numberOfDaysProvider()
116 | {
117 | return array(
118 | array('2003', Month::JANUARY, 31),
119 | array('2003', Month::FEBRURY, 28),
120 | array('2004', Month::FEBRURY, 29),
121 | array('2003', Month::MARCH, 31),
122 | array('2003', Month::APRIL, 30),
123 | array('2003', Month::MAY, 31),
124 | array('2003', Month::JUNE, 30),
125 | array('2003', Month::JULY, 31),
126 | array('2003', Month::AUGUST, 31),
127 | array('2003', Month::SEPTEMBER, 30),
128 | array('2003', Month::OCTOBER, 31),
129 | array('2003', Month::NOVEMBER, 30),
130 | array('2003', Month::DECEMBER, 31),
131 | );
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/BmCalendar/Calendar.php:
--------------------------------------------------------------------------------
1 |
18 | */
19 | class Calendar
20 | {
21 | /**
22 | * The system which configures day objects.
23 | *
24 | * @var DayProviderInterface
25 | */
26 | protected $dayProvider;
27 |
28 | /**
29 | * Initialise the class.
30 | *
31 | * @param DayProviderInterface $dayProvider
32 | */
33 | public function __construct(DayProviderInterface $dayProvider = null)
34 | {
35 | $this->dayProvider = $dayProvider;
36 | }
37 |
38 | /**
39 | * Returns a year object for the given year number.
40 | *
41 | * @param int $yearNo
42 | * @return Year
43 | */
44 | public function getYear($yearNo)
45 | {
46 | return new Year($yearNo);
47 | }
48 |
49 | /**
50 | * Checks the type of the provided parameter and returns the appropriate Year.
51 | *
52 | * @param int|Year $year
53 | * @return Year
54 | * @throws InvalidArgumentException
55 | */
56 | protected function yearOrYearNo($year)
57 | {
58 | if (is_scalar($year)) {
59 | return $this->getYear($year);
60 | }
61 |
62 | if (!$year instanceof Year) {
63 | throw new InvalidArgumentException(
64 | '$year must be an instance of BmCalendar\Year; got "' . get_class($year) . '"'
65 | );
66 | }
67 |
68 | return $year;
69 | }
70 |
71 | /**
72 | * Returns the appropriate Month object.
73 | *
74 | * @param int|Year $year
75 | * @param int $monthNo
76 | * @return Month
77 | */
78 | public function getMonth($year, $monthNo)
79 | {
80 | $year = $this->yearOrYearNo($year);
81 |
82 | return new Month($year, $monthNo);
83 | }
84 |
85 | /**
86 | * Get this months for the given year.
87 | *
88 | * @param int|Year $year
89 | * @return Month[]
90 | */
91 | public function getMonths($year)
92 | {
93 | $year = $this->yearOrYearNo($year);
94 |
95 | $months = array();
96 |
97 | for ($monthNo = 1; $monthNo <= 12; $monthNo++) {
98 | $months[$monthNo] = new Month($year, $monthNo);
99 | }
100 |
101 | return $months;
102 | }
103 |
104 | /**
105 | * Returns the requested day object.
106 | *
107 | * @param Month $month
108 | * @param int $dayNo
109 | * @return DayInterface
110 | */
111 | public function getDay(Month $month, $dayNo)
112 | {
113 | $dayNo = (int) $dayNo;
114 |
115 | if (null === $this->dayProvider) {
116 | return new Day($month, $dayNo);
117 | }
118 |
119 | $day = $this->dayProvider->createDay($month, $dayNo);
120 |
121 | if (!$day instanceof DayInterface) {
122 | throw new DomainException(
123 | '$day must be instance of BmCalendar\DayInterface; got '
124 | . is_object($day) ? get_class($day) : gettype($day)
125 | );
126 | }
127 |
128 | if ($day->value() !== $dayNo) {
129 | throw new DomainException(
130 | "The value of the day is wrong, it should be $dayNo but is actually "
131 | . $day->value()
132 | );
133 | }
134 |
135 | if ($day->getMonth() !== $month) {
136 | throw new DomainException(
137 | 'The day returned from the day provider contains the wrong Month.'
138 | );
139 | }
140 |
141 | return $day;
142 | }
143 |
144 | /**
145 | * Returns all the days for the given month.
146 | *
147 | * @param Month $month
148 | * @return DayInterface[]
149 | */
150 | public function getDays(Month $month)
151 | {
152 | $days = array();
153 |
154 | for ($dayNo = 1; $dayNo <= $month->numberOfDays(); $dayNo++) {
155 | $days[$dayNo] = $this->getDay($month, $dayNo);
156 | }
157 |
158 | return $days;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/BmCalendar/View/Helper/Calendar.php:
--------------------------------------------------------------------------------
1 |
23 | */
24 | class Calendar extends AbstractHelper
25 | {
26 | /**
27 | * The {@see CalendarObject} object to be rendered.
28 | *
29 | * @var CalendarObject
30 | */
31 | protected $calendar;
32 |
33 | /**
34 | * The name of the template used to render the calendar.
35 | *
36 | * @var null|string
37 | */
38 | protected $partial;
39 |
40 | /**
41 | * Class to generate HTML version of the calendar.
42 | *
43 | * @var Renderer
44 | */
45 | protected $renderer;
46 |
47 | /**
48 | * The day to start a week on.
49 | *
50 | * @var mixed
51 | */
52 | protected $startDay = DayInterface::MONDAY;
53 |
54 | /**
55 | * Returns the {@see CalendarObject} to be rendered.
56 | *
57 | * @return CalendarObject
58 | */
59 | public function getCalendar()
60 | {
61 | return $this->calendar;
62 | }
63 |
64 | /**
65 | * Sets the value of partial
66 | *
67 | * @param string $partial
68 | * @return self
69 | */
70 | public function setPartial($partial)
71 | {
72 | $this->partial = (string) $partial;
73 | return $this;
74 | }
75 |
76 | /**
77 | * Gets the value of partial
78 | *
79 | * @return string
80 | */
81 | public function getPartial()
82 | {
83 | return $this->partial;
84 | }
85 |
86 | /**
87 | * Set which day to display as the starting day of the week.
88 | *
89 | * @param int $startDay
90 | * @return self
91 | */
92 | public function setStartDay($startDay)
93 | {
94 | $startDay = (int) $startDay;
95 |
96 | if ($startDay < 1 || $startDay > 7) {
97 | throw new OutOfRangeException(
98 | "'$startDay' is an invalid value for \$startDay in '"
99 | . __METHOD__
100 | );
101 | }
102 |
103 | $this->startDay = $startDay;
104 |
105 | return $this;
106 | }
107 |
108 | /**
109 | * Sets which day of the week the rendering will begin on.
110 | *
111 | * @return void
112 | */
113 | public function getStartDay()
114 | {
115 | return $this->startDay;
116 | }
117 |
118 | /**
119 | * Set the renderer to be used.
120 | *
121 | * @param Renderer $renderer
122 | *
123 | * @return self
124 | * @todo Accept closure to generate renderer.
125 | */
126 | public function setRenderer(Renderer $renderer)
127 | {
128 | $this->renderer = $renderer;
129 | return $this;
130 | }
131 |
132 | /**
133 | * Gets the value of renderer
134 | *
135 | * @return Renderer
136 | */
137 | public function getRenderer()
138 | {
139 | return $this->renderer;
140 | }
141 |
142 | /**
143 | * Returns the HTML to display a month.
144 | *
145 | * @param int $year
146 | * @param int $month
147 | * @return void
148 | */
149 | public function showMonth($year, $month)
150 | {
151 | if (null !== $this->partial) {
152 | $partial = $this->view->plugin('partial');
153 |
154 | $params = array(
155 | 'calendar' => $this->calendar,
156 | 'startDay' => $this->startDay,
157 | 'year' => $year,
158 | 'month' => $month,
159 | );
160 |
161 | return $partial($this->partial, $params);
162 | }
163 |
164 | $renderer = $this->getRenderer();
165 |
166 | $renderer->setCalendar($this->calendar);
167 | $renderer->setStartDay($this->startDay);
168 |
169 | return $renderer->renderMonth($year, $month);
170 | }
171 |
172 | /**
173 | * The entry point for the view helper.
174 | *
175 | * This method saves the {@see CalendarObject} to which is to be rendered
176 | * and then returns itself to expose it's public interface.
177 | *
178 | * @param CalendarObject $calendar
179 | * @return self
180 | */
181 | public function __invoke(CalendarObject $calendar)
182 | {
183 | $this->calendar = $calendar;
184 | $this->partial = null;
185 |
186 | return $this;
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | BmCalendar
2 | ==========
3 |
4 | [](https://travis-ci.org/SCLInternet/BmCalendar)
5 | [](https://coveralls.io/r/SCLInternet/BmCalendar?branch=master)
6 |
7 | Calendar module which provide the ability to block off days.
8 |
9 | Installation
10 | ------------
11 |
12 | Installation can be done easily via composer by running:
13 |
14 | `composer.php require sclinternet/bm-calendar`
15 |
16 | When prompted for a version enter `dev-master`.
17 |
18 | After the composer has completed simple add `BmCalendar` to the `modules`
19 | section in your application config.
20 |
21 | Basic Usage
22 | -----------
23 |
24 | Simply create a calendar like so:
25 |
26 | ```php
27 | $calendar = new \BmCalendar\Calendar();
28 | ```
29 |
30 | And the use the view helper to display a month in your view:
31 |
32 | ```php
33 | echo $this->calendar($calendar)->showMonth(2013, 05);
34 | ```
35 |
36 | The View Helper
37 | ---------------
38 |
39 | By default the view helper will render a month in a simple HTML table created by
40 | `BmCalendar\Renderer\HtmlCalendar`.
41 |
42 | Changing the start day
43 | ======================
44 |
45 | By default the calendar will render with Monday days in the first column, if
46 | you wish to change this you can invoke the view helper like so.
47 |
48 | ```php
49 | echo $this->calendar($calendar)
50 | ->setStartDay(\BmCalendar\DayInterface::WEDNESDAY)
51 | ->showMonth(2013, 5);
52 | ```
53 |
54 | Renderer Classes
55 | ================
56 |
57 | You can also create your own renderer classes by implementing
58 | `BmCalendar\Renderer\RendererInterface` then tell the view helper to use your
59 | renderer instead like so:
60 |
61 | ```php
62 | echo $this->calendar($calendar)->setRenderer(new MyRenderer())->showMonth(2013, 5);
63 | ```
64 |
65 | Partials
66 | ========
67 |
68 | Alternatively you can customise the rendering process by using partial templates.
69 |
70 |
71 | To do this simply call the view helper like so:
72 |
73 | ```php
74 | echo $this->calendar($calendar)->setPartial('partial-name')->showMonth(2013, 5);
75 | ```
76 |
77 | The partial will have the following parameters passed to it:
78 |
79 | * **$startDay** - The day of the week to start the calendar on (int 1-7)
80 | * **$calendar** - An instance of `BmCalendar\Calendar`
81 | * **$month** - The month to be rendered (int)
82 | * **$year** - The year that the month to be rendered belongs to (int)
83 |
84 | Day Providers
85 | -------------
86 |
87 | Day providers are used to add extra states to a day.
88 |
89 | States must implement `\BmCalendar\State\DayStateInterface`.
90 |
91 | A day provider can be implemented like so:
92 |
93 | ```php
94 | use BmCalendar\DayProviderInterface;
95 | use BmCalendar\Day;
96 | use BmCalendar\Month;
97 |
98 | class MyDayProvider implements DayProviderInterface
99 | {
100 | public $database;
101 |
102 | public function createDay(Month $month, $dayNo)
103 | {
104 | $day = new Day($month, $dayNo);
105 |
106 | $avaliable = $this->database->checkAvailability(
107 | $month->getYear()->value(),
108 | $month->value(),
109 | $dayNo
110 | );
111 |
112 | if (!$available) {
113 | $day->addState(new BookedState());
114 |
115 | return $day;
116 | }
117 |
118 | $day->addState(new AvailableState());
119 | $day->setAction('http://url-to-booking-form');
120 |
121 | return $day;
122 | }
123 | }
124 | ```
125 |
126 | To use your day provider simply pass it to the Calendar constructor like so:
127 |
128 | ```php
129 | $provider = new MyDayProvider();
130 | $provider->database = new AvailabilityDatabasesChecker();
131 |
132 | $calendar = new \BmCalendar\Calendar($provider);
133 | ```
134 |
135 | Day States
136 | ----------
137 | Day states allow you to add values to days in the calendar (e.g. if there is
138 | an event on on that day).
139 |
140 |
141 | ### Creating a day state class
142 | A day state is a class which implements `BmCalendar\State\DayStateInterface` which
143 | simply provides a static method called `type()` to identify the state by.
144 |
145 | There is also a `BmCalendar\State\AbstractDayState` class available which can be
146 | directly extended which will implement the `type()` method for you.
147 |
148 | You can quickly define a state like so:
149 |
150 | ```php
151 | use BmCalendar\State\AbstractDayState;
152 |
153 | class HasEventState extends AbstractDayState
154 | {
155 | }
156 | ```
157 |
158 | ### Using day states
159 |
160 | To add a state to a `Day` object you simply call the `addState($state)` method:
161 |
162 | ```php
163 | $day->addState(new HasEventState())
164 | ```
165 |
166 | To get a list of all states attached to a `Day` object you can call
167 |
168 | ```php
169 | $day->getStates();
170 | ```
171 |
172 | An if you want to check for a specific type of state for a given day you can
173 | use the static `type()` method like so:
174 |
175 | ```php
176 | $state = $day->getState(HasEventState::type());
177 | ```
178 |
179 | If the `Day` doesn't contain a state of the requested type `NULL` is returned.
180 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/DayTest.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class DayTest extends \PHPUnit_Framework_TestCase
22 | {
23 | /**
24 | * Check that if the day of the month is less than 1 an exception is thrown.
25 | *
26 | * @covers BmCalendar\Day::__construct
27 | * @expectedException BmCalendar\Exception\OutOfRangeException
28 | *
29 | * @return void
30 | */
31 | public function testDayValueTooLow()
32 | {
33 | $day = new Day(new Month(new Year(2013), 5), 0);
34 | }
35 |
36 | /**
37 | * Check that if the day of the month is greater than the number of days in
38 | * the month an exception is thrown.
39 | *
40 | * @covers BmCalendar\Day::__construct
41 | * @expectedException BmCalendar\Exception\OutOfRangeException
42 | *
43 | * @return void
44 | */
45 | public function testDayValueTooHigh()
46 | {
47 | $day = new Day(new Month(new Year(2013), 4), 31);
48 | }
49 |
50 | /**
51 | * Test getting the values back from a Day object.
52 | *
53 | * @covers BmCalendar\Day::value
54 | * @covers BmCalendar\Day::__construct
55 | * @covers BmCalendar\Day::__toString
56 | */
57 | public function testValue()
58 | {
59 | $month = new Month(new Year(2013), Month::JANUARY);
60 | $day = new Day($month, 25);
61 |
62 | $this->assertEquals($month, $day->getMonth(), 'The month object is incorrect.');
63 |
64 | $this->assertEquals(25, $day->value(), 'The value of the day is incorrect.');
65 |
66 | $this->assertEquals('25', (string) $day, 'String representation of the day is wrong.');
67 | }
68 |
69 | /**
70 | * Tests that the day of the week is correctly calculated.
71 | *
72 | * @covers BmCalendar\Day::dayOfWeek
73 | */
74 | public function testDayOfWeek()
75 | {
76 | $today = new \DateTime();
77 |
78 | $year = (int) $today->format('Y');
79 | $month = (int) $today->format('m');
80 | $day = (int) $today->format('j');
81 |
82 | $dayOfWeek = $today->format('N');
83 |
84 | $dayObject = new Day(new Month(new Year($year), $month), $day);
85 |
86 | $this->assertEquals($dayOfWeek, $dayObject->dayOfWeek(), 'The day of the week doesn\'t match.');
87 | }
88 |
89 | /**
90 | * Test that states are added to a Day object correctly.
91 | *
92 | * @covers BmCalendar\Day::addState
93 | * @covers BmCalendar\Day::getStates
94 | *
95 | * @return void
96 | */
97 | public function testGetStates()
98 | {
99 | $state1 = new State\MockStateA();
100 | $state2 = new State\MockStateB();
101 |
102 | $day = new Day(new Month(new Year(2013), 6), 17);
103 |
104 | $day->addState($state1)
105 | ->addState($state2);
106 |
107 | $this->assertEquals(
108 | array(State\MockStateA::type() => $state1, State\MockStateB::type() => $state2),
109 | $day->getStates(),
110 | 'Get states didn\'t return all the states'
111 | );
112 | }
113 |
114 | /**
115 | * Test the getState method.
116 | *
117 | * @covers BmCalendar\Day::getState
118 | * @covers BmCalendar\Day::addState
119 | *
120 | * @return void
121 | */
122 | public function testGetState()
123 | {
124 | $state = new State\MockStateA();
125 |
126 | $day = new Day(new Month(new Year(2013), 6), 17);
127 |
128 | $day->addState($state);
129 |
130 | $this->assertEquals(
131 | $state,
132 | $day->getState(State\MockStateA::type()),
133 | 'Failed to get the requested state.'
134 | );
135 | }
136 |
137 | /**
138 | * Test the getState with bad type.
139 | *
140 | * @covers BmCalendar\Day::getState
141 | * @covers BmCalendar\Day::addState
142 | *
143 | * @return void
144 | */
145 | public function testGetStateWithBadType()
146 | {
147 | $day = new Day(new Month(new Year(2013), 6), 17);
148 |
149 | $this->assertNull(
150 | $day->getState('xxx'),
151 | 'Get state which doesn\'t exist didn\'t return null.'
152 | );
153 | }
154 |
155 | /**
156 | * testAction
157 | *
158 | * @covers BmCalendar\Day::setAction
159 | * @covers BmCalendar\Day::getAction
160 | *
161 | * @return void
162 | */
163 | public function testGetSetAction()
164 | {
165 | $action = 'the_action';
166 |
167 | $day = new Day(new Month(new Year(2013), 6), 17);
168 |
169 | $result = $day->setAction($action);
170 |
171 | $this->assertEquals($day, $result, 'Interface is not fluent.');
172 |
173 | $result = $day->getAction();
174 |
175 | $this->assertEquals($action, $result, 'Incorrect action.');
176 | }
177 |
178 | /**
179 | * testAction
180 | *
181 | * @covers BmCalendar\Day::__construct
182 | * @covers BmCalendar\Day::getMonth
183 | *
184 | * @return void
185 | */
186 | public function testGetMonth()
187 | {
188 | $month = new Month(new Year(2013), 6);
189 |
190 | $day = new Day($month, 17);
191 |
192 | $result = $day->getMonth();
193 |
194 | $this->assertEquals($month, $result, 'Incorrect month.');
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/BmCalendar/Renderer/HtmlCalendar.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class HtmlCalendar implements CalendarRendererInterface
22 | {
23 | /**
24 | * The names of the 12 months.
25 | *
26 | * @var string[]
27 | */
28 | protected static $monthNames = array(
29 | 1 => 'January',
30 | 2 => 'February',
31 | 3 => 'March',
32 | 4 => 'April',
33 | 5 => 'May',
34 | 6 => 'June',
35 | 7 => 'July',
36 | 8 => 'August',
37 | 9 => 'September',
38 | 10 => 'October',
39 | 11 => 'November',
40 | 12 => 'December'
41 | );
42 |
43 | /**
44 | * The names of the 7 days of the week.
45 | *
46 | * @var string[]
47 | */
48 | protected static $dayNames = array(
49 | DayInterface::MONDAY => 'Mon',
50 | DayInterface::TUESDAY => 'Tue',
51 | DayInterface::WEDNESDAY => 'Wed',
52 | DayInterface::THURSDAY => 'Thu',
53 | DayInterface::FRIDAY => 'Fri',
54 | DayInterface::SATURDAY => 'Sat',
55 | DayInterface::SUNDAY => 'Sun',
56 | );
57 |
58 | /**
59 | * The calendar.
60 | *
61 | * @var Calendar
62 | */
63 | protected $calendar;
64 |
65 | /**
66 | * The day to start a week on.
67 | *
68 | * @var mixed
69 | */
70 | protected $startDay = DayInterface::MONDAY;
71 |
72 | /**
73 | * {@inheritDoc}
74 | *
75 | * @param Calendar $calendar
76 | * @return self
77 | */
78 | public function setCalendar(Calendar $calendar)
79 | {
80 | $this->calendar = $calendar;
81 |
82 | return $this;
83 | }
84 |
85 | /**
86 | * {@inheritDoc}
87 | *
88 | * @param int $startDay
89 | * @return self
90 | */
91 | public function setStartDay($startDay)
92 | {
93 | $startDay = (int) $startDay;
94 |
95 | if ($startDay < 1 || $startDay > 7) {
96 | throw new OutOfRangeException(
97 | "'$startDay' is an invalid value for \$startDay in '"
98 | . __METHOD__
99 | );
100 | }
101 |
102 | $this->startDay = $startDay;
103 |
104 | return $this;
105 | }
106 |
107 | /**
108 | * Returns the markup for the header of a month table.
109 | *
110 | * @param Month $month
111 | * @return string
112 | */
113 | public function monthTitle(Month $month)
114 | {
115 | $weekendClass = 'bm-calendar-weekend';
116 |
117 | $monthName = self::$monthNames[$month->value()];
118 |
119 | $output = '';
120 | $output .= '';
121 |
122 | $output .= '| ' . $monthName . ' | ';
123 |
124 | $output .= '
';
125 |
126 | // Display the headings for the days of the week.
127 | for ($column = 0; $column < 7; $column++) {
128 | $day = ($column + $this->startDay - 1) % 7 + 1;
129 |
130 | if (DayInterface::SATURDAY === $day || DayInterface::SUNDAY === $day) {
131 | $output .= '| ';
132 | } else {
133 | $output .= ' | ';
134 | }
135 | $output .= self::$dayNames[$day];
136 | $output .= ' | ';
137 | }
138 |
139 | $output .= '
';
140 | $output .= '';
141 |
142 | return $output;
143 | }
144 |
145 | /**
146 | * Returns the markup for a single table cell.
147 | *
148 | * @param DayInterface $day
149 | * @return string
150 | */
151 | public function renderDay(DayInterface $day)
152 | {
153 | $classes = array();
154 |
155 | $dayOfWeek = $day->dayOfWeek();
156 |
157 | if (DayInterface::SATURDAY === $dayOfWeek || DayInterface::SUNDAY === $dayOfWeek) {
158 | $classes[] = 'bm-calendar-weekend';
159 | }
160 |
161 | foreach ($day->getStates() as $state) {
162 | $classes[] = 'bm-calendar-state-' . $state->type();
163 | }
164 |
165 | $output = '
';
166 | if (sizeof($classes)) {
167 | $output = ' | ';
168 | }
169 |
170 | if ($day->getAction()) {
171 | $output .= '' . $day . '';
172 | } else {
173 | $output .= $day;
174 | }
175 |
176 |
177 | $output .= ' | ';
178 |
179 | return $output;
180 | }
181 |
182 | /**
183 | * Render a month table internally.
184 | *
185 | * @param int $yearNo
186 | * @param int $monthNo
187 | * @return string
188 | */
189 | public function renderMonth($year, $month)
190 | {
191 | $monthClass = sprintf('bm-calendar-month-%02d', $month);
192 | $yearClass = sprintf('bm-calendar-year-%04d', $year);
193 |
194 | $month = $this->calendar->getMonth($year, $month);
195 | $days = $this->calendar->getDays($month);
196 |
197 | $column = 0;
198 |
199 | $output = '';
200 |
201 | $output .= $this->monthTitle($month);
202 |
203 | $output .= '';
204 |
205 | $output .= '';
206 |
207 | $blankCells = ($month->startDay() - $this->startDay + 7) % 7;
208 |
209 | while ($column < $blankCells) {
210 | $output .= ' | ';
211 | $column++;
212 | }
213 |
214 | foreach ($days as $day) {
215 | if (1 !== $day->value() && 0 === $column) {
216 | $output .= '
';
217 | }
218 |
219 | $output .= $this->renderDay($day, $column);
220 |
221 | $column = ($column + 1) % 7;
222 | }
223 |
224 | while ($column < 7) {
225 | $output .= ' | ';
226 | $column++;
227 | }
228 |
229 | $output .= '
';
230 |
231 | $output .= '';
232 |
233 | $output .= '
';
234 |
235 | return $output;
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/Renderer/HtmlCalendarTest.php:
--------------------------------------------------------------------------------
1 |
21 | */
22 | class HtmlCalendarTests extends \PHPUnit_Framework_TestCase
23 | {
24 | /**
25 | * The instance to be tested.
26 | *
27 | * @var HtmlCalendar
28 | */
29 | protected $renderer;
30 |
31 | /**
32 | * Prepare the instance to be tested
33 | *
34 | * @return void
35 | */
36 | protected function setUp()
37 | {
38 | $this->renderer = new HtmlCalendar;
39 | }
40 |
41 | /**
42 | * Test that set start day with a bad value raises and exception.
43 | *
44 | * @covers BmCalendar\Renderer\HtmlCalendar::setStartDay
45 | * @expectedException BmCalendar\Exception\OutOfRangeException
46 | *
47 | * @return void
48 | */
49 | public function testSetStartDayWithInvalidValue()
50 | {
51 | $this->renderer->setStartDay(8);
52 | }
53 |
54 | /**
55 | * Test the output of monthTitle.
56 | *
57 | * @covers BmCalendar\Renderer\HtmlCalendar::monthTitle
58 | *
59 | * @return void
60 | */
61 | public function testMonthTitle()
62 | {
63 | $month = new Month(new Year(2013), 3);
64 |
65 | $expected = '';
66 | $expected .= '';
67 | $expected .= '| March | ';
68 | $expected .= '
';
69 | $expected .= '| Mon | ';
70 | $expected .= 'Tue | ';
71 | $expected .= 'Wed | ';
72 | $expected .= 'Thu | ';
73 | $expected .= 'Fri | ';
74 | $expected .= 'Sat | ';
75 | $expected .= 'Sun | ';
76 | $expected .= '
';
77 | $expected .= '';
78 |
79 | $this->assertEquals($expected, $this->renderer->monthTitle($month));
80 | }
81 |
82 | /**
83 | * Test the output of monthTitle starting on a Wednesday.
84 | *
85 | * @covers BmCalendar\Renderer\HtmlCalendar::setStartDay
86 | * @covers BmCalendar\Renderer\HtmlCalendar::monthTitle
87 | *
88 | * @return void
89 | */
90 | public function testMonthTitleStartingOnWednesday()
91 | {
92 | $month = new Month(new Year(2013), 3);
93 |
94 | $expected = '';
95 | $expected .= '';
96 | $expected .= '| March | ';
97 | $expected .= '
';
98 | $expected .= '| Wed | ';
99 | $expected .= 'Thu | ';
100 | $expected .= 'Fri | ';
101 | $expected .= 'Sat | ';
102 | $expected .= 'Sun | ';
103 | $expected .= 'Mon | ';
104 | $expected .= 'Tue | ';
105 | $expected .= '
';
106 | $expected .= '';
107 |
108 | $this->renderer->setStartDay(Day::WEDNESDAY);
109 |
110 | $this->assertEquals($expected, $this->renderer->monthTitle($month));
111 | }
112 |
113 | /**
114 | * Test the output of renderDay with a week day with no state or action.
115 | *
116 | * @covers BmCalendar\Renderer\HtmlCalendar::renderDay
117 | * @dataProvider weekdayProvider
118 | *
119 | * @return void
120 | */
121 | public function testRenderDayWithWeekday($dom, $dayName)
122 | {
123 | // 7th March 2013 was a Thursday
124 | $day = new Day(new Month(new Year(2013), 3), $dom);
125 |
126 | $expected = '' . $dom . ' | ';
127 |
128 | $this->assertEquals(
129 | $expected,
130 | $this->renderer->renderDay($day),
131 | 'Error on week day ' . $dayName . ' with no states or action'
132 | );
133 | }
134 |
135 | /**
136 | * Test the output of renderDay with a weekend day with no state or action.
137 | *
138 | * @covers BmCalendar\Renderer\HtmlCalendar::renderDay
139 | * @dataProvider weekendProvider
140 | *
141 | * @return void
142 | */
143 | public function testRenderDayWithWeekendDay($dom, $dayName)
144 | {
145 | // 9th March 2013 was a Saturday
146 | $day = new Day(new Month(new Year(2013), 3), $dom);
147 |
148 | $expected = '' . $dom . ' | ';
149 |
150 | $this->assertEquals(
151 | $expected,
152 | $this->renderer->renderDay($day),
153 | 'Error on ' . $dayName . ' day with no states or action'
154 | );
155 | }
156 |
157 | public function weekendProvider()
158 | {
159 | return array(
160 | array(9, 'Saturday'),
161 | array(10, 'Sunday')
162 | );
163 | }
164 |
165 | public function weekdayProvider()
166 | {
167 | return array(
168 | array(11,'Monday'),
169 | array(12,'Tuesday'),
170 | array(13,'Wednesday'),
171 | array(14,'Thursday'),
172 | array(15,'Friday'),
173 | );
174 | }
175 |
176 | /**
177 | * Test the output of renderDay with a week day with an action.
178 | *
179 | * @covers BmCalendar\Renderer\HtmlCalendar::renderDay
180 | *
181 | * @return void
182 | */
183 | public function testRenderDayWithAction()
184 | {
185 | // Test with an action
186 | $day = new Day(new Month(new Year(2013), 3), 7);
187 |
188 | $actionUrl = 'http://dosome.action/index?param1=value¶m2=value';
189 | $day->setAction($actionUrl);
190 |
191 | $expected = '7 | ';
192 |
193 | $this->assertEquals(
194 | $expected,
195 | $this->renderer->renderDay($day),
196 | 'Error on week day with no states or an action'
197 | );
198 | }
199 |
200 | /**
201 | * Test the output of renderDay with a week day with a state.
202 | *
203 | * @covers BmCalendar\Renderer\HtmlCalendar::renderDay
204 | *
205 | * @return void
206 | */
207 | public function testRenderDayWithAState()
208 | {
209 | // Test with a state
210 | $day = new Day(new Month(new Year(2013), 3), 7);
211 |
212 | $expected = '7 | ';
213 |
214 | $state = new MockStateA();
215 |
216 | $day->addState($state);
217 |
218 | $this->assertEquals(
219 | $expected,
220 | $this->renderer->renderDay($day),
221 | 'Error on week day with states and no action'
222 | );
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/View/Helper/CalendarTest.php:
--------------------------------------------------------------------------------
1 |
18 | */
19 | class CalendarTest extends \PHPUnit_Framework_TestCase
20 | {
21 | /**
22 | * The instance to be tested.
23 | *
24 | * @var Calendar
25 | */
26 | protected $helper;
27 |
28 | /**
29 | * A mock view.
30 | *
31 | * @var Zend\View\Renderer\RendererInterface
32 | */
33 | protected $view;
34 |
35 | /**
36 | * Prepare the object to test.
37 | *
38 | * @return void
39 | */
40 | protected function setUp()
41 | {
42 | $this->helper = new Calendar();
43 |
44 | $this->view = $this->getMock('Zend\View\Renderer\PhpRenderer');
45 |
46 | $this->helper->setView($this->view);
47 | }
48 |
49 | /**
50 | * Test that set start day with a bad value raises and exception.
51 | *
52 | * @covers BmCalendar\View\Helper\Calendar::setStartDay
53 | * @expectedException BmCalendar\Exception\OutOfRangeException
54 | *
55 | * @return void
56 | */
57 | public function testSetStartDayWithInvalidValue()
58 | {
59 | $this->helper->setStartDay(8);
60 | }
61 |
62 | /**
63 | * Test that the getStartDay and setStartDay methods work as expected.
64 | *
65 | * @covers BmCalendar\View\Helper\Calendar::setStartDay
66 | * @covers BmCalendar\View\Helper\Calendar::getStartDay
67 | *
68 | * @return void
69 | */
70 | public function testSetGetStartDay()
71 | {
72 | $this->assertEquals(
73 | DayInterface::MONDAY,
74 | $this->helper->getStartDay(),
75 | 'Start day was not initialised to Monday'
76 | );
77 |
78 | $days = array(
79 | DayInterface::MONDAY,
80 | DayInterface::TUESDAY,
81 | DayInterface::WEDNESDAY,
82 | DayInterface::THURSDAY,
83 | DayInterface::FRIDAY,
84 | DayInterface::SATURDAY,
85 | DayInterface::SUNDAY,
86 | );
87 |
88 | foreach ($days as $day) {
89 | $result = $this->helper->setStartDay($day);
90 |
91 | $this->assertSame($this->helper, $result, 'setStartDay() did not return $this');
92 |
93 | $this->assertEquals(
94 | $day,
95 | $this->helper->getStartDay(),
96 | 'getStartDay() returnered incorrect value for ' . $day . '.'
97 | );
98 | }
99 | }
100 |
101 | /**
102 | * Tests the partial value is stored.
103 | *
104 | * @covers BmCalendar\View\Helper\Calendar::setPartial
105 | * @covers BmCalendar\View\Helper\Calendar::getPartial
106 | *
107 | * @return void
108 | */
109 | public function testSetPartial()
110 | {
111 | $partialName = 'test-partial';
112 |
113 | $this->helper->setPartial($partialName);
114 |
115 | $this->assertEquals($partialName, $this->helper->getPartial(), 'The partial name was not saved.');
116 | }
117 |
118 | /**
119 | * Test that the calendar to be used it set.
120 | *
121 | * @covers BmCalendar\View\Helper\Calendar::__invoke
122 | * @covers BmCalendar\View\Helper\Calendar::getCalendar
123 | * @depends testSetPartial
124 | *
125 | * @return void
126 | */
127 | public function testSetCalendar()
128 | {
129 | $calendar = $this->getMock('BmCalendar\Calendar');
130 |
131 | $this->helper->setPartial('xxx');
132 |
133 | $result = $this->helper->__invoke($calendar);
134 |
135 | $this->assertEquals($this->helper, $result, 'The helper didn\'t return itself.');
136 |
137 | $this->assertEquals($calendar, $this->helper->getCalendar(), 'The calendar has not been saved in the view helper');
138 |
139 | $this->assertNull($this->helper->getPartial(), 'Partial wasn\'t reset.');
140 | }
141 |
142 | /**
143 | * Test the actual rendering of the calendar.
144 | *
145 | * @covers BmCalendar\View\Helper\Calendar::showMonth
146 | * @depends testSetPartial
147 | * @depends testSetCalendar
148 | *
149 | * @return void
150 | */
151 | public function testShowMonthWithPartial()
152 | {
153 | $output = 'THE_CALENDAR';
154 | $partialName = 'the-partial';
155 | $year = 2013;
156 | $month = 7;
157 | $startDay = 5;
158 |
159 | $calendar = $this->getMock('BmCalendar\Calendar');
160 | $params = array(
161 | 'calendar' => $calendar,
162 | 'startDay' => $startDay,
163 | 'year' => $year,
164 | 'month' => $month,
165 | );
166 |
167 | $partial = $this->getMock('Zend\View\Helper\Partial');
168 |
169 | $this->view->expects($this->once())
170 | ->method('plugin')
171 | ->with($this->equalTo('partial'))
172 | ->will($this->returnValue($partial));
173 |
174 | $partial->expects($this->once())
175 | ->method('__invoke')
176 | ->with($this->equalTo($partialName), $this->equalTo($params))
177 | ->will($this->returnValue($output));
178 |
179 | $this->helper->__invoke($calendar);
180 | $this->helper->setPartial($partialName);
181 | $this->helper->setStartDay($startDay);
182 |
183 | $result = $this->helper->showMonth($year, $month);
184 |
185 | $this->assertEquals($output, $result, 'The output didn\'t match.');
186 | }
187 |
188 | /**
189 | * Test the internal rendering of the calendar.
190 | *
191 | * @covers BmCalendar\View\Helper\Calendar::showMonth
192 | * @covers BmCalendar\View\Helper\Calendar::setRenderer
193 | * @covers BmCalendar\View\Helper\Calendar::getRenderer
194 | * @depends testSetCalendar
195 | *
196 | * @return void
197 | */
198 | public function testShowWithRenderer()
199 | {
200 | $year = 2013;
201 | $month = 7;
202 | $result = 'Calendar';
203 | $startDay = 3;
204 |
205 | $calendar = $this->getMock('BmCalendar\Calendar');
206 |
207 | $renderer = $this->getMock('BmCalendar\Renderer\CalendarRendererInterface');
208 |
209 | $renderer->expects($this->once())
210 | ->method('setCalendar')
211 | ->with($this->equalTo($calendar));
212 |
213 | $renderer->expects($this->once())
214 | ->method('setStartDay')
215 | ->with($this->equalTo($startDay));
216 |
217 | $renderer->expects($this->once())
218 | ->method('renderMonth')
219 | ->with($this->equalTo($year), $this->equalTo($month))
220 | ->will($this->returnValue($result));
221 |
222 | $this->helper->setStartDay($startDay);
223 |
224 | $this->helper->__invoke($calendar);
225 |
226 | $this->helper->setRenderer($renderer);
227 |
228 | $this->assertEquals(
229 | $result,
230 | $this->helper->showMonth($year, $month)
231 | );
232 | }
233 | }
234 |
--------------------------------------------------------------------------------
/tests/BmCalendarTests/CalendarTest.php:
--------------------------------------------------------------------------------
1 |
21 | */
22 | class CalendarTest extends \PHPUnit_Framework_TestCase
23 | {
24 | /**
25 | * Mock day provider.
26 | *
27 | * @var DayProviderInterface
28 | */
29 | protected $dayProvider;
30 |
31 | /**
32 | * The object used for testing.
33 | *
34 | * @var Calendar
35 | */
36 | protected $calendar;
37 |
38 | /**
39 | * Prepare the object to be tested.
40 | */
41 | protected function setUp()
42 | {
43 | $this->dayProvider = $this->getMock('BmCalendar\DayProviderInterface');
44 |
45 | $this->calendar = new Calendar($this->dayProvider);
46 | }
47 |
48 | /**
49 | * Check that the Year returned contains the correct value.
50 | *
51 | * @covers BmCalendar\Calendar::getYear
52 | *
53 | * @return void
54 | */
55 | public function testGetYear()
56 | {
57 | $yearNo = 2013;
58 |
59 | $year = $this->calendar->getYear($yearNo);
60 |
61 | $this->assertEquals($yearNo, $year->value(), 'The year object is incorrect.');
62 | }
63 |
64 | /**
65 | * Check that the Month returned contains the correct value.
66 | *
67 | * @covers BmCalendar\Calendar::getMonth
68 | * @covers BmCalendar\Calendar::yearOrYearNo
69 | *
70 | * @return void
71 | */
72 | public function testGetMonthFromScalarYear()
73 | {
74 | $yearNo = 2013;
75 | $monthNo = 5;
76 |
77 | $month = $this->calendar->getMonth($yearNo, $monthNo);
78 | $year = $month->getYear();
79 |
80 | $this->assertEquals($yearNo, $year->value(), 'The year object is incorrect.');
81 | $this->assertEquals($monthNo, $month->value(), 'The month object is incorrect.');
82 | }
83 |
84 | /**
85 | * Check that the Month returned contains the correct value.
86 | *
87 | * @covers BmCalendar\Calendar::getMonth
88 | *
89 | * @return void
90 | */
91 | public function testGetMonthFromYearObject()
92 | {
93 | $year = new Year(2013);
94 | $monthNo = 5;
95 |
96 | $month = $this->calendar->getMonth($year, $monthNo);
97 |
98 | $this->assertEquals($year->value(), $month->getYear()->value(), 'The year object is incorrect.');
99 | $this->assertEquals($monthNo, $month->value(), 'The month object is incorrect.');
100 | }
101 |
102 | /**
103 | * Check that an exception is throw if bad parameters are given.
104 | *
105 | * @covers BmCalendar\Calendar::yearOrYearNo
106 | * @covers BmCalendar\Calendar::getMonth
107 | * @expectedException BmCalendar\Exception\InvalidArgumentException
108 | *
109 | * @return void
110 | */
111 | public function testGetMonthWithBadYearObject()
112 | {
113 | $year = new \stdClass();
114 | $monthNo = 5;
115 |
116 | $month = $this->calendar->getMonth($year, $monthNo);
117 | }
118 |
119 | /**
120 | * Test for the getMonths method()
121 | *
122 | * @covers BmCalendar\Calendar::getMonths
123 | * @covers BmCalendar\Calendar::yearOrYearNo
124 | *
125 | * @return void
126 | */
127 | public function testGetMonths()
128 | {
129 | $year = new Year(2015);
130 |
131 | $months = $this->calendar->getMonths($year);
132 |
133 | $this->assertCount(12, $months, 'There must be 12 months in a year.');
134 |
135 | $monthNo = 1;
136 | foreach ($months as $month) {
137 | $this->assertEquals($monthNo, $month->value(), 'Month value is incorrect.');
138 |
139 | $this->assertEquals($year, $month->getYear(), 'The month is from the wrong year');
140 |
141 | $monthNo++;
142 | }
143 | }
144 |
145 | /**
146 | * Test getDay with a good day provider.
147 | *
148 | * @covers BmCalendar\Calendar::getDay
149 | * @covers BmCalendar\Calendar::__construct
150 | *
151 | * @return void
152 | */
153 | public function testGetDayWithGoodDayProvider()
154 | {
155 | $requestedDay = 13;
156 |
157 | $month = $this->calendar->getMonth(1999, 3);
158 | $day = new Day($month, $requestedDay);
159 |
160 | $this->dayProvider
161 | ->expects($this->once())
162 | ->method('createDay')
163 | ->with($this->equalTo($month), $this->equalTo($requestedDay))
164 | ->will($this->returnValue($day));
165 |
166 | $this->assertEquals($day, $this->calendar->getDay($month, $requestedDay));
167 | }
168 |
169 | /**
170 | * Test that when a day is created with a value which doesn't match the requested
171 | * day then an exception is thrown.
172 | *
173 | * @covers BmCalendar\Calendar::getDay
174 | * @expectedException BmCalendar\Exception\DomainException
175 | *
176 | * @return void
177 | */
178 | public function testGetDayWithValueNotMatchingRequestedDay()
179 | {
180 | $requestedDay = 13;
181 |
182 | $month = $this->calendar->getMonth(1999, 3);
183 | $day = new Day($month, 22);
184 |
185 | $this->dayProvider
186 | ->expects($this->once())
187 | ->method('createDay')
188 | ->with($this->equalTo($month), $this->equalTo($requestedDay))
189 | ->will($this->returnValue($day));
190 |
191 | $this->calendar->getDay($month, $requestedDay);
192 | }
193 |
194 | /**
195 | * Test that when a day is created with a value which doesn't match the requested
196 | * day then an exception is thrown.
197 | *
198 | * @covers BmCalendar\Calendar::getDay
199 | * @expectedException BmCalendar\Exception\DomainException
200 | *
201 | * @return void
202 | */
203 | public function testGetDayWithWrongMonthValue()
204 | {
205 | $requestedDay = 13;
206 |
207 | $month = $this->calendar->getMonth(1999, 3);
208 |
209 | $day = new Day(new Month(new Year(2000), 1), $requestedDay);
210 |
211 | $this->dayProvider
212 | ->expects($this->once())
213 | ->method('createDay')
214 | ->with($this->equalTo($month), $this->equalTo($requestedDay))
215 | ->will($this->returnValue($day));
216 |
217 | $this->calendar->getDay($month, $requestedDay);
218 | }
219 |
220 | /**
221 | * Test getDay with a bad day provider.
222 | *
223 | * @covers BmCalendar\Calendar::getDay
224 | * @expectedException BmCalendar\Exception\DomainException
225 | *
226 | * @return void
227 | */
228 | public function testGetDayWithBadDayProvider()
229 | {
230 | $requestedDay = 13;
231 |
232 | $month = $this->calendar->getMonth(1999, 3);
233 |
234 | $this->dayProvider
235 | ->expects($this->once())
236 | ->method('createDay')
237 | ->will($this->returnValue(new \stdClass()));
238 |
239 | $day = $this->calendar->getDay($month, 13);
240 | }
241 |
242 | /**
243 | * Test getDay with no day provider.
244 | *
245 | * @covers BmCalendar\Calendar::getDay
246 | *
247 | * @return void
248 | */
249 | public function testGetDayWithNoDayProvider()
250 | {
251 | $requestedDay = 25;
252 |
253 | $calendar = new Calendar();
254 |
255 | $month = $calendar->getMonth(2001, 3);
256 |
257 | $day = $calendar->getDay($month, 25);
258 |
259 | $this->assertInstanceOf('BmCalendar\DayInterface', $day);
260 | $this->assertEquals($month, $day->getMonth());
261 | $this->assertEquals(25, $day->value());
262 | }
263 |
264 | /**
265 | * testGetDays
266 | *
267 | * @covers BmCalendar\Calendar::getDays
268 | *
269 | * @return void
270 | */
271 | public function testGetDays()
272 | {
273 | $month = new Month(new Year(2013), 3);
274 |
275 | $calendar = new Calendar();
276 |
277 | $days = $calendar->getDays($month);
278 |
279 | $this->assertCount(31, $days);
280 |
281 | $dayNo = 1;
282 | foreach ($days as $day) {
283 | $this->assertInstanceOf('BmCalendar\DayInterface', $days[$dayNo]);
284 | $this->assertEquals($dayNo, $day->value());
285 | $this->assertEquals($month, $day->getMonth());
286 | $dayNo++;
287 | }
288 | }
289 | }
290 |
--------------------------------------------------------------------------------