├── .gitignore
├── src
└── Ddd
│ ├── Time
│ ├── .gitignore
│ ├── Tests
│ │ ├── TestCase.php
│ │ ├── Model
│ │ │ ├── FixedDateIntervalTest.php
│ │ │ ├── DateTest.php
│ │ │ ├── DateIntervalTest.php
│ │ │ ├── TimePointTest.php
│ │ │ ├── FixedDateTest.php
│ │ │ ├── DurationTest.php
│ │ │ └── TimeIntervalTest.php
│ │ ├── Factory
│ │ │ ├── TimePointFactoryTest.php
│ │ │ ├── DateIntervalFactoryTest.php
│ │ │ └── TimeIntervalFactoryTest.php
│ │ └── HowTo
│ │ │ ├── TimeOfDayTest.php
│ │ │ ├── TimeIntervalTest.php
│ │ │ ├── DurationTest.php
│ │ │ ├── DateIntervalTest.php
│ │ │ ├── TimePointTest.php
│ │ │ └── DateTest.php
│ ├── phpunit.xml.dist
│ ├── Factory
│ │ ├── DateFactory.php
│ │ ├── DurationFactory.php
│ │ ├── TimePointFactory.php
│ │ ├── DateIntervalFactory.php
│ │ └── TimeIntervalFactory.php
│ ├── Model
│ │ ├── IntervalInterface.php
│ │ ├── FixedDate.php
│ │ ├── TimeUnit.php
│ │ ├── TimeInterval.php
│ │ ├── FixedDateInterval.php
│ │ ├── TimeOfDay.php
│ │ ├── DateInterval.php
│ │ ├── Date.php
│ │ ├── TimePoint.php
│ │ └── Duration.php
│ ├── Bridge
│ │ └── Doctrine
│ │ │ └── Types
│ │ │ ├── DateType.php
│ │ │ ├── TimePointType.php
│ │ │ ├── DateIntervalType.php
│ │ │ └── TimeIntervalType.php
│ ├── composer.json
│ └── README.md
│ ├── Calendar
│ ├── .gitignore
│ ├── Tests
│ │ ├── TestCase.php
│ │ ├── HowTo
│ │ │ ├── DoctorCalendarRepository.php
│ │ │ └── CalendarTest.php
│ │ └── Model
│ │ │ └── CalendarTest.php
│ ├── Exception
│ │ ├── CalendarExceptionInterface.php
│ │ └── CalendarEventException.php
│ ├── Service
│ │ ├── EventProviderInterface.php
│ │ ├── CalendarPersisterInterface.php
│ │ ├── EventPersisterInterface.php
│ │ └── CalendarLoaderInterface.php
│ ├── Model
│ │ ├── NamedEventInterface.php
│ │ ├── SendableEventInterface.php
│ │ ├── EventInterface.php
│ │ ├── Event.php
│ │ ├── Strategy
│ │ │ ├── NoOverlapStrategy.php
│ │ │ ├── FrozenStrategy.php
│ │ │ ├── StrategyInterface.php
│ │ │ ├── BaseStrategy.php
│ │ │ └── PersistenceStrategy.php
│ │ ├── NamedEvent.php
│ │ ├── SendableEvent.php
│ │ ├── CalendarInterface.php
│ │ └── Calendar.php
│ ├── README.md
│ ├── phpunit.xml.dist
│ ├── composer.json
│ └── Infra
│ │ └── EventProvider.php
│ ├── Mail
│ ├── Model
│ │ ├── TextMail.php
│ │ ├── Contact.php
│ │ └── Mail.php
│ ├── Service
│ │ └── MailerInterface.php
│ ├── Exception
│ │ ├── MailNotComposedException.php
│ │ └── MailWithoutRecipientException.php
│ ├── Infra
│ │ └── Mailer
│ │ │ ├── NullMailer.php
│ │ │ ├── SwiftMailer.php
│ │ │ └── AmazonSesMailer.php
│ ├── composer.json
│ ├── Tests
│ │ └── Acceptance
│ │ │ ├── MailBuilderTest.php
│ │ │ ├── BasicMailTest.php
│ │ │ └── TextMailTest.php
│ ├── MailBuilder.php
│ └── README.md
│ └── Slug
│ ├── Tests
│ ├── Resources
│ │ └── db.sqlite
│ ├── TestDatabase.php
│ ├── Fixtures
│ │ ├── InMemoryArticle.php
│ │ └── DoctrineArticle.php
│ ├── AcceptanceDataProvider.php
│ └── AcceptanceTest.php
│ ├── Model
│ └── SluggableInterface.php
│ ├── Infra
│ ├── Transliterator
│ │ ├── PassthruTransliterator.php
│ │ ├── LatinTransliterator.php
│ │ └── TransliteratorCollection.php
│ └── SlugGenerator
│ │ ├── PassthruSlugGenerator.php
│ │ └── DefaultSlugGenerator.php
│ ├── Service
│ ├── SlugGeneratorInterface.php
│ └── TransliteratorInterface.php
│ ├── composer.json
│ └── README.md
├── scripts
└── do-split.sh
├── README.md
├── phpunit.xml.dist
└── composer.json
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 | composer.lock
3 |
--------------------------------------------------------------------------------
/src/Ddd/Time/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | *.swp
3 | vendor
4 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | *.swp
3 | vendor
4 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/Model/TextMail.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 | interface CalendarExceptionInterface
9 | {
10 | function getMessage();
11 | }
12 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Service/EventProviderInterface.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Service/CalendarPersisterInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Tests
7 |
8 |
9 | Tests/HowTo
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Tests
7 |
8 |
9 | Tests/HowTo
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Service/EventPersisterInterface.php:
--------------------------------------------------------------------------------
1 | sent = $sent;
15 | }
16 |
17 | public function send(Mail $mail)
18 | {
19 | return $this->sent ? array() : $mail->getRecipients();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Service/CalendarLoaderInterface.php:
--------------------------------------------------------------------------------
1 | format('Y'),
20 | $dateTime->format('m'),
21 | $dateTime->format('d')
22 | );
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Model/SluggableInterface.php:
--------------------------------------------------------------------------------
1 |
11 | * @author Jean-François Simon
12 | */
13 | interface SluggableInterface
14 | {
15 | /**
16 | * Slugifies entity using given slugifier.
17 | *
18 | * @param SlugGeneratorInterface $slugifier
19 | */
20 | public function slugify(SlugGeneratorInterface $slugifier);
21 | }
22 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Infra/Transliterator/PassthruTransliterator.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class PassthruTransliterator implements TransliteratorInterface
11 | {
12 | /**
13 | * {@inheritdoc}
14 | */
15 | public function transliterate($string)
16 | {
17 | return $string;
18 | }
19 |
20 | public function getName()
21 | {
22 | return 'passthru';
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Factory/DurationFactory.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class PassthruSlugGenerator implements SlugGeneratorInterface
13 | {
14 | /**
15 | * {@inheritdoc}
16 | */
17 | public function slugify(array $fieldValues, array $options = array())
18 | {
19 | return implode('', $fieldValues);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ddd/mail",
3 | "type": "library",
4 | "description": "",
5 | "keywords": ["mail","ddd"],
6 | "homepage": "https://github.com/ddd-php/Mail",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "Joseph ROUFF",
11 | "email": "rouffj@gmail.com",
12 | "homepage": "http://josephrouff.com"
13 | }
14 | ],
15 | "require": {
16 | "php": ">=5.3.0"
17 | },
18 | "autoload": {
19 | "psr-0": { "Ddd\\Mail": "" }
20 | },
21 | "target-dir": "Ddd/Mail"
22 | }
23 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/Model/Contact.php:
--------------------------------------------------------------------------------
1 | email = $email;
13 | $this->name = $name;
14 | }
15 |
16 | public function getEmail()
17 | {
18 | return $this->email;
19 | }
20 |
21 | public function getName()
22 | {
23 | return $this->name;
24 | }
25 |
26 | public function toString()
27 | {
28 | return sprintf("%s <%s>", $this->name, $this->email);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Service/SlugGeneratorInterface.php:
--------------------------------------------------------------------------------
1 |
9 | * @author Jean-François Simon
10 | */
11 | interface SlugGeneratorInterface
12 | {
13 | /**
14 | * Slugifies an array of string values.
15 | *
16 | * @param array $fieldValues
17 | * @param array $options See implementations for available options
18 | *
19 | * @return string
20 | */
21 | public function slugify(array $fieldValues, array $options = array());
22 | }
23 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Service/TransliteratorInterface.php:
--------------------------------------------------------------------------------
1 |
9 | * @author Jean-François Simon
10 | */
11 | interface TransliteratorInterface
12 | {
13 | /**
14 | * Transliterates given string to ascii.
15 | *
16 | * @param string $string
17 | *
18 | * @return string
19 | */
20 | public function transliterate($string);
21 |
22 | /**
23 | * Name of the transliterator
24 | *
25 | * @return string
26 | */
27 | public function getName();
28 | }
29 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/IntervalInterface.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 | interface IntervalInterface
9 | {
10 | public function getBegin();
11 | public function getEnd();
12 | public function isBefore(IntervalInterface $interval);
13 | public function isAfter(IntervalInterface $interval);
14 | public function isDuring(IntervalInterface $interval);
15 | public function isInclude(IntervalInterface $interval);
16 | public function isPartiallyBefore(IntervalInterface $interval);
17 | public function isPartiallyAfter(IntervalInterface $interval);
18 | }
19 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/Event.php:
--------------------------------------------------------------------------------
1 | interval = $interval;
14 | }
15 |
16 | public function getInterval()
17 | {
18 | return $this->interval;
19 | }
20 |
21 | public function isEquals(EventInterface $event)
22 | {
23 | return $this->interval->getBegin()->isEquals($event->getInterval()->getBegin())
24 | && $this->interval->getEnd()->isEquals($event->getInterval()->getEnd());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Tests/TestDatabase.php:
--------------------------------------------------------------------------------
1 | databasePath = __DIR__.'/Resources/db.sqlite';
13 | $this->backupPath = __DIR__.'/Resources/db.backup';
14 | }
15 |
16 | public static function backup()
17 | {
18 | $database = new self();
19 | copy($database->databasePath, $database->backupPath);
20 | }
21 |
22 | public static function restore()
23 | {
24 | $database = new self();
25 | rename($database->backupPath, $database->databasePath);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Bridge/Doctrine/Types/DateType.php:
--------------------------------------------------------------------------------
1 | toDateTime());
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Tests/Fixtures/InMemoryArticle.php:
--------------------------------------------------------------------------------
1 | slug = $slugifier->slugify(array($this->title));
16 | }
17 |
18 | public function setTitle($title)
19 | {
20 | $this->title = $title;
21 | }
22 |
23 | public function getTitle()
24 | {
25 | return $this->title;
26 | }
27 |
28 | public function getSlug()
29 | {
30 | return $this->slug;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ddd/slug",
3 | "type": "library",
4 | "description": "",
5 | "keywords": ["slug", "ddd"],
6 | "homepage": "https://github.com/ddd-php/Slug",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "Joseph ROUFF",
11 | "email": "rouffj@gmail.com",
12 | "homepage": "http://josephrouff.com"
13 | },
14 | {
15 | "name": "Jean-François Simon",
16 | "email": "contact@jfsimon.fr",
17 | "homepage": "http://www.jfsimon.fr"
18 | }
19 | ],
20 | "require": {
21 | "php": ">=5.3.0",
22 | "ext-iconv": "*"
23 | },
24 | "autoload": {
25 | "psr-0": { "Ddd\\Slug": "" }
26 | },
27 | "target-dir": "Ddd/Slug"
28 | }
29 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ddd/calendar",
3 | "type": "library",
4 | "description": "",
5 | "keywords": ["time","calendar"],
6 | "homepage": "https://github.com/ddd-php/Calendar",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "Joseph ROUFF",
11 | "email": "rouffj@gmail.com",
12 | "homepage": "http://josephrouff.com"
13 | },
14 | {
15 | "name": "Jean-François Simon",
16 | "email": "contact@jfsimon.fr",
17 | "homepage": "http://www.jfsimon.fr"
18 | }
19 | ],
20 | "require": {
21 | "php": ">=5.3.0",
22 | "ddd/time": "*"
23 | },
24 | "autoload": {
25 | "psr-0": { "Ddd\\Calendar": "" }
26 | },
27 | "target-dir": "Ddd/Calendar"
28 | }
29 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/Strategy/NoOverlapStrategy.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | class NoOverlapStrategy extends BaseStrategy
15 | {
16 | /**
17 | * {@inheritdoc}
18 | */
19 | public function add(EventInterface $newEvent, array $events)
20 | {
21 | foreach ($events as $event) {
22 | if ($newEvent->getInterval()->isDuring($event->getInterval())) {
23 | throw CalendarEventException::eventOverlap($newEvent);
24 | }
25 | }
26 |
27 | return parent::add($newEvent, $events);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Infra/EventProvider.php:
--------------------------------------------------------------------------------
1 |
7 | */
8 | class EventProvider implements EventProviderInterface
9 | {
10 | /**
11 | * @var string
12 | */
13 | private $name;
14 |
15 | /**
16 | * @var array
17 | */
18 | private $events;
19 |
20 | /**
21 | * @param string $name
22 | * @param array $events
23 | */
24 | public function __construct($name, array $events)
25 | {
26 | $this->name = $name;
27 | $this->events = $events;
28 | }
29 |
30 | /**
31 | * @return array
32 | */
33 | public function getEvents()
34 | {
35 | return $this->events;
36 | }
37 |
38 | /**
39 | * @return string
40 | */
41 | public function getName()
42 | {
43 | return $this->name;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Ddd/Time/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ddd/time",
3 | "type": "library",
4 | "description": "",
5 | "keywords": ["time","money"],
6 | "homepage": "https://github.com/ddd-php/Time",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "Joseph ROUFF",
11 | "email": "rouffj@gmail.com",
12 | "homepage": "http://josephrouff.com"
13 | },
14 | {
15 | "name": "Jean-François Simon",
16 | "email": "contact@jfsimon.fr",
17 | "homepage": "http://www.jfsimon.fr"
18 | },
19 | {
20 | "name": "Julien GALENSKI",
21 | "email": "julien.galenski@gmail.com",
22 | "homepage": "http://www.jgalenski.fr"
23 | }
24 | ],
25 | "require": {
26 | "php": ">=5.3.0"
27 | },
28 | "autoload": {
29 | "psr-0": { "Ddd\\Time": "" }
30 | },
31 | "target-dir": "Ddd/Time"
32 | }
33 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Tests/AcceptanceDataProvider.php:
--------------------------------------------------------------------------------
1 | assertTrue($interval->isInclude(DateIntervalFactory::create('2013-01-13', '2013-01-14')));
18 | $this->assertTrue($interval->isInclude(DateIntervalFactory::create('2013-10-13', '2013-10-15')));
19 | $this->assertTrue($interval->isInclude(DateIntervalFactory::create('2013-05-14', '2013-05-15')));
20 | $this->assertTrue($interval->isInclude(TimeIntervalFactory::create('2013-01-13 01:00', '2013-01-14 18:30')));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 | ./src/Ddd/*/Tests/*
17 |
18 |
19 | ./src/Ddd/*/Tests/HowTo
20 |
21 |
22 |
23 |
24 | ./src/Ddd
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Model/DateTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, $date->isAfter(new Date(2011, 11, 25)));
14 | $this->assertEquals(true, $date->isAfter(new Date(2012, 10, 1)));
15 | $this->assertEquals(true, $date->isAfter(new Date(2012, 11, 1)));
16 |
17 | $this->assertEquals(false, $date->isAfter(new Date(2012, 11, 2)));
18 | $this->assertEquals(false, $date->isAfter(new Date(2012, 11, 5)));
19 | $this->assertEquals(false, $date->isAfter(new Date(2012, 12, 5)));
20 | }
21 |
22 | public function testToDateTime()
23 | {
24 | $date = new Date(2013, 1, 1);
25 |
26 | $this->assertEquals(new \DateTime('2013-01-01 00:00:00'), $date->toDateTime());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Factory/TimePointFactoryTest.php:
--------------------------------------------------------------------------------
1 | assertNull(TimePointFactory::fromTimestamp(null));
14 | $this->assertNull(TimePointFactory::fromTimestamp(0));
15 | $this->assertNull(TimePointFactory::fromTimestamp(false));
16 | $this->assertNull(TimePointFactory::fromTimestamp('times 5'));
17 | }
18 |
19 | public function testFromTimestampWhenValidValueGiven()
20 | {
21 | $this->assertEquals(new TimePoint(1970, 1, 1, 0, 0, 5), TimePointFactory::fromTimestamp(5));
22 | $this->assertEquals(new TimePoint(1970, 1, 1, 0, 0, 2), TimePointFactory::fromTimestamp('2*5'), 'should return UNIX time begin + 2 seconds because string starts with a number');
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/HowTo/TimeOfDayTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, $first->isBefore($second));
18 | $this->assertEquals(true, $third->isAfter($second));
19 | $this->assertEquals(true, $four->isEquals($third));
20 | }
21 |
22 | public function testHowToKnowIfItIsTheAnteMeridianPostMeridian()
23 | {
24 | $ante = new TimeOfDay(11, 59, 59);
25 | $post = new TimeOfDay(12, 37, 21);
26 | $this->assertEquals(true, $ante->isAnteMeridian());
27 | $this->assertEquals(true, $post->isPostMeridian());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Factory/DateIntervalFactoryTest.php:
--------------------------------------------------------------------------------
1 | fail('An exception should be thrown');
17 | } catch (\InvalidArgumentException $e) {
18 | $this->assertEquals('The given interval "2010-01,2010-01-02" does not respect the expected format: "Y-m-d,Y-m-d".', $e->getMessage());
19 | }
20 | }
21 |
22 | public function testCreateWhenValidFormat()
23 | {
24 | $interval = DateIntervalFactory::create('2010-01-01', '2010-01-02');
25 | $this->assertEquals(new DateInterval(new Date(2010, 1, 1), new Date(2010, 1, 2)), $interval);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ddd/components",
3 | "type": "library",
4 | "description": "Domain Driven Design components (Slug...).",
5 | "keywords": ["slugifier", "slug", "url", "DDD", "Domain Driven Design"],
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Joseph Rouff",
10 | "email": "rouffj@gmail.com"
11 | },
12 | {
13 | "name": "Jean-François Simon",
14 | "email": "contact@jfsimon.fr"
15 | }
16 | ],
17 | "require": {
18 | "php": ">=5.3.0"
19 | },
20 | "suggest": {
21 | "swiftmailer/swiftmailer": "[Mailer] Allow use of SwiftMailer as MailerInterface implementation",
22 | "aws/aws-sdk-php": "[Mailer] Allow to use Amazon SES as MailerInterface implementation"
23 | },
24 | "require-dev": {
25 | "doctrine/orm": "2.3",
26 | "swiftmailer/swiftmailer": "*",
27 | "aws/aws-sdk-php": "*"
28 | },
29 | "autoload": {
30 | "psr-0": { "Ddd": "src/" }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Factory/TimePointFactory.php:
--------------------------------------------------------------------------------
1 | setTimestamp($timestamp);
25 |
26 | return self::fromDateTime($dateTime);
27 | }
28 |
29 | static public function fromDateTime(\DateTime $dateTime)
30 | {
31 | return new TimePoint(
32 | $dateTime->format('Y'),
33 | $dateTime->format('m'),
34 | $dateTime->format('d'),
35 | $dateTime->format('H'),
36 | $dateTime->format('i'),
37 | $dateTime->format('s')
38 | );
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/Strategy/FrozenStrategy.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | class FrozenStrategy implements StrategyInterface
14 | {
15 | /**
16 | * {@inheritdoc}
17 | */
18 | public function add(EventInterface $newEvent, array $events)
19 | {
20 | throw CalendarEventException::addWhileFrozen($newEvent);
21 | }
22 |
23 | /**
24 | * {@inheritdoc}
25 | */
26 | public function remove(EventInterface $removedEvent, array $events)
27 | {
28 | throw CalendarEventException::removeWhileFrozen($removedEvent);
29 | }
30 | /**
31 | * {@inheritdoc}
32 | */
33 | public function update(EventInterface $originalEvent, EventInterface $updatedEvent, array $events)
34 | {
35 | throw CalendarEventException::updateWhileFrozen($originalEvent);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Factory/TimeIntervalFactoryTest.php:
--------------------------------------------------------------------------------
1 | fail('An exception should be thrown');
17 | } catch (\InvalidArgumentException $e) {
18 | $this->assertEquals('The given interval "2010-01-01 00,2010-01-01 05:00" does not respect the expected format: "Y-m-d G:i,Y-m-d G:i".', $e->getMessage());
19 | }
20 | }
21 |
22 | public function testCreateWhenValidFormat()
23 | {
24 | $interval = TimeIntervalFactory::create('2010-01-01 00:00', '2010-01-01 05:00');
25 | $this->assertEquals(new TimeInterval(new TimePoint(2010, 1, 1, 0, 0), new TimePoint(2010, 1, 1, 5, 0)), $interval);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Factory/DateIntervalFactory.php:
--------------------------------------------------------------------------------
1 | format('Y'),
18 | $now->format('m'),
19 | $now->format('d')
20 | );
21 | }
22 |
23 | static public function create($beginString, $endString)
24 | {
25 | $begin = \DateTime::createFromFormat(self::FORMAT_DATE, $beginString);
26 | $end = \DateTime::createFromFormat(self::FORMAT_DATE, $endString);
27 |
28 | if (!$begin || !$end) {
29 | throw new \InvalidArgumentException(sprintf('The given interval "%s,%s" does not respect the expected format: "%s,%s".', $beginString, $endString, self::FORMAT_DATE, self::FORMAT_DATE));
30 | }
31 |
32 | return new DateInterval(DateFactory::fromDateTime($begin), DateFactory::fromDateTime($end));
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/NamedEvent.php:
--------------------------------------------------------------------------------
1 | title = $title;
27 | }
28 |
29 | /**
30 | * {@inheritdoc}
31 | */
32 | public function getTitle()
33 | {
34 | return $this->title;
35 | }
36 |
37 | /**
38 | * @param string $description
39 | */
40 | public function setDescription($description)
41 | {
42 | $this->description = $description;
43 | }
44 |
45 | /**
46 | * {@inheritdoc}
47 | */
48 | public function getDescription()
49 | {
50 | return $this->description;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/Tests/Acceptance/MailBuilderTest.php:
--------------------------------------------------------------------------------
1 | addRecipients(array(
18 | 'recipient1@bar.com',
19 | 'recipient2@bar.com' => 'Recipient 2',
20 | 'recipient3@bar.com',
21 | ))
22 | ->compose('My subject', 'My body')
23 | ;
24 |
25 | $mail = $builder->getTextMail();
26 |
27 | $expectedMail = new TextMail(new Contact('sender@foo.bar', 'John Doo'));
28 | $expectedMail
29 | ->addRecipient(new Contact('recipient1@bar.com'))
30 | ->addRecipient(new Contact('recipient2@bar.com', 'Recipient 2'))
31 | ->addRecipient(new Contact('recipient3@bar.com'))
32 | ->compose('My subject', 'My body')
33 | ;
34 | $this->assertEquals($expectedMail, $mail);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Tests/Fixtures/DoctrineArticle.php:
--------------------------------------------------------------------------------
1 | id;
29 | }
30 |
31 | public function slugify(SlugGeneratorInterface $slugifier)
32 | {
33 | $this->slug = $slugifier->slugify(array($this->title));
34 | }
35 |
36 | public function setTitle($title)
37 | {
38 | $this->title = $title;
39 | }
40 |
41 | public function getTitle()
42 | {
43 | return $this->title;
44 | }
45 |
46 | public function getSlug()
47 | {
48 | return $this->slug;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Bridge/Doctrine/Types/TimePointType.php:
--------------------------------------------------------------------------------
1 | getDateTimeTypeDeclarationSQL($fieldDeclaration);
15 | }
16 |
17 | public function convertToPHPValue($value, AbstractPlatform $platform)
18 | {
19 | $dtime = \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);
20 | if (!$dtime) {
21 | throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString());
22 | }
23 |
24 | return TimePointFactory::fromDateTime($dtime);
25 | }
26 |
27 | public function convertToDatabaseValue($timepoint, AbstractPlatform $platform)
28 | {
29 | if ($timepoint !== null) {
30 | $dtime = $timepoint->toDateTime();
31 | return $dtime->format($platform->getDateTimeFormatString());
32 | }
33 | }
34 |
35 | public function getName()
36 | {
37 | return self::TIMEPOINT;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Bridge/Doctrine/Types/DateIntervalType.php:
--------------------------------------------------------------------------------
1 | getVarcharTypeDeclarationSQL($fieldDeclaration);
15 | }
16 |
17 | public function convertToPHPValue($dateIntervalFromDatabase, AbstractPlatform $platform)
18 | {
19 | list($begin, $end) = explode(',', $dateIntervalFromDatabase);
20 |
21 | return DateIntervalFactory::create($begin, $end);
22 | }
23 |
24 | public function convertToDatabaseValue($dateInterval, AbstractPlatform $platform)
25 | {
26 | if ($dateInterval !== null) {
27 | $beginString = $dateInterval->getBegin()->toDateTime()->format($platform->getDateFormatString());
28 | $endString = $dateInterval->getEnd()->toDateTime()->format($platform->getDateFormatString());
29 | }
30 |
31 | return sprintf('%s,%s', $beginString, $endString);
32 | }
33 |
34 | public function getName()
35 | {
36 | return self::DATE_INTERVAL;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Tests/HowTo/DoctorCalendarRepository.php:
--------------------------------------------------------------------------------
1 | calendar = new Calendar('Doctor Smith\'s appointments', array(
20 | new Event(TimeIntervalFactory::create('2012-01-01 8:00', '2012-01-01 09:00')),
21 | new Event(TimeIntervalFactory::create('2012-01-05 8:00', '2012-01-05 10:15')),
22 | new Event(TimeIntervalFactory::create('2012-01-10 15:00', '2012-01-10 15:30')),
23 | ));
24 | }
25 |
26 | public function load()
27 | {
28 | return $this->calendar;
29 | }
30 |
31 | public function loadInterval(TimeInterval $interval)
32 | {
33 | return $this->calendar->between($interval);
34 | }
35 |
36 | public function persist(CalendarInterface $calendar)
37 | {
38 | $this->calendar = $calendar;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Factory/TimeIntervalFactory.php:
--------------------------------------------------------------------------------
1 | getBegin();
28 | $end = $dateInterval->getEnd();
29 |
30 | return new TimeInterval(
31 | new TimePoint($begin->getYear(), $begin->getMonth(), $begin->getDay(), 0, 0),
32 | new TimePoint($end->getYear(), $end->getMonth(), $end->getDay(), 23, 59, 59)
33 | );
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Bridge/Doctrine/Types/TimeIntervalType.php:
--------------------------------------------------------------------------------
1 | getVarcharTypeDeclarationSQL($fieldDeclaration);
15 | }
16 |
17 | public function convertToPHPValue($timepointIntervalFromDatabase, AbstractPlatform $platform)
18 | {
19 | list($begin, $end) = explode(',', $timepointIntervalFromDatabase);
20 |
21 | return TimeIntervalFactory::create($begin, $end);
22 | }
23 |
24 | public function convertToDatabaseValue($timepointInterval, AbstractPlatform $platform)
25 | {
26 | if ($timepointInterval !== null) {
27 | $beginString = $timepointInterval->getBegin()->toDateTime()->format($platform->getDateTimeFormatString());
28 | $endString = $timepointInterval->getEnd()->toDateTime()->format($platform->getDateTimeFormatString());
29 | }
30 |
31 | return sprintf('%s,%s', $beginString, $endString);
32 | }
33 |
34 | public function getName()
35 | {
36 | return self::TIME_INTERVAL;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Infra/Transliterator/LatinTransliterator.php:
--------------------------------------------------------------------------------
1 |
9 | * @author Jean-François Simon
10 | */
11 | class LatinTransliterator implements TransliteratorInterface
12 | {
13 | /**
14 | * @var string
15 | */
16 | private $inputEncoding;
17 |
18 | /**
19 | * @todo: enumerate here all possible accents
20 | */
21 | private $availableAccents = array(
22 | '\'', '`', '^', '~'
23 | );
24 |
25 | /**
26 | * @param string $inputEncoding
27 | */
28 | public function __construct($inputEncoding = 'utf-8')
29 | {
30 | $this->inputEncoding = $inputEncoding;
31 | }
32 |
33 | /**
34 | * {@inheritdoc}
35 | */
36 | public function transliterate($string)
37 | {
38 | $transliteration = iconv($this->inputEncoding, 'us-ascii//TRANSLIT', $string);
39 |
40 | return ('Darwin' === PHP_OS) ? $this->removeAloneAccents($transliteration) : $transliteration;
41 | }
42 |
43 | public function getName()
44 | {
45 | return 'latin';
46 | }
47 |
48 | private function removeAloneAccents($transliteration)
49 | {
50 | return str_replace($this->availableAccents, '', $transliteration);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/SendableEvent.php:
--------------------------------------------------------------------------------
1 | organizer = $organizer;
27 | $this->guests = array();
28 | }
29 |
30 | /**
31 | * @return string
32 | */
33 | public function getOrganizer()
34 | {
35 | return $this->organizer;
36 | }
37 |
38 | public function addGuest($guest)
39 | {
40 | $this->guests[] = $guest;
41 | }
42 |
43 | public function removeGuest($guest)
44 | {
45 | if ($index = array_search($guest, $this->guests)) {
46 | array_slice($this->guests, $index, 1);
47 | }
48 | }
49 |
50 | public function hasGuest($guest)
51 | {
52 | return in_array($guest, $this->guests);
53 | }
54 |
55 | /**
56 | * @return array
57 | */
58 | public function getGuests()
59 | {
60 | return $this->guests;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/MailBuilder.php:
--------------------------------------------------------------------------------
1 | from = new Contact($senderAddress, $senderName);
18 | }
19 |
20 | public static function create($senderAddress, $senderName)
21 | {
22 | return new static($senderAddress, $senderName);
23 | }
24 |
25 | public function addRecipients(array $recipients)
26 | {
27 | foreach ($recipients as $key => $value) {
28 | if (is_int($key)) {
29 | $recipient = new Contact($value, null);
30 | } else {
31 | $recipient = new Contact($key, $value);
32 | }
33 |
34 | $this->recipients[$recipient->getEmail()] = $recipient;
35 | }
36 |
37 | return $this;
38 | }
39 |
40 | public function compose($subject, $body)
41 | {
42 | $this->subject = $subject;
43 | $this->body = $body;
44 |
45 | return $this;
46 | }
47 |
48 | public function getTextMail()
49 | {
50 | $mail = new TextMail($this->from);
51 | $mail->compose($this->subject, $this->body);
52 | foreach ($this->recipients as $recipient) {
53 | $mail->addRecipient($recipient);
54 | }
55 |
56 | return $mail;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/FixedDate.php:
--------------------------------------------------------------------------------
1 | month = (null === $month) ? null : (int) $month;
13 | $this->day = (int) $day;
14 | }
15 |
16 | public function isAfter(Date $date)
17 | {
18 | if (!$this->month) {
19 | return $this->day > $date->getDay();
20 | }
21 |
22 | return
23 | $this->month > $date->getMonth() ||
24 | ($this->month >= $date->getMonth() && $this->day > $date->getDay())
25 | ;
26 | }
27 |
28 | public function isBefore(Date $date)
29 | {
30 | return
31 | false === $this->isAfter($date) &&
32 | false === $this->isEquals($date)
33 | ;
34 | }
35 |
36 | public function isEquals(Date $date)
37 | {
38 | if (!$this->month) {
39 | return $this->day === $date->getDay();
40 | }
41 |
42 | return
43 | $this->month === $date->getMonth() &&
44 | $this->day === $date->getDay()
45 | ;
46 | }
47 |
48 | /**
49 | * Gets the value of month
50 | *
51 | * @return int
52 | */
53 | public function getMonth()
54 | {
55 | return $this->month;
56 | }
57 |
58 | /**
59 | * Gets the value of day
60 | *
61 | * @return int
62 | */
63 | public function getDay()
64 | {
65 | return $this->day;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/CalendarInterface.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | interface CalendarInterface extends \IteratorAggregate, \Countable, \ArrayAccess
17 | {
18 | /**
19 | * @param TimeInterval $interval
20 | * @param string $title
21 | *
22 | * @return CalendarInterface
23 | */
24 | public function between(TimeInterval $interval, $title = '');
25 |
26 | /**
27 | * @param EventInterface $newEvent
28 | */
29 | public function add(EventInterface $newEvent);
30 |
31 | /**
32 | * @param EventInterface $event
33 | */
34 | public function remove(EventInterface $event);
35 |
36 | /**
37 | * @param EventInterface $originalEvent
38 | * @param EventInterface $updatedEvent
39 | */
40 | public function update(EventInterface $originalEvent, EventInterface $updatedEvent);
41 |
42 | /**
43 | * @param TimePoint $cursor
44 | */
45 | public function setCursor(TimePoint $cursor);
46 |
47 | /**
48 | * @return TimePoint
49 | */
50 | public function getCursor();
51 |
52 | /**
53 | * @return string
54 | */
55 | public function getTitle();
56 |
57 | /**
58 | * {@inheritdoc}
59 | */
60 | public function countRemaining();
61 | }
62 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/Strategy/StrategyInterface.php:
--------------------------------------------------------------------------------
1 | unit = $unit;
20 | }
21 |
22 | public function getCode()
23 | {
24 | return (self::MINUTE === $this->unit) ? 'M' : $this->unit;
25 | }
26 |
27 | public function getUnit()
28 | {
29 | return $this->unit;
30 | }
31 |
32 | public function isTime()
33 | {
34 | return
35 | self::HOUR === $this->unit ||
36 | self::MINUTE === $this->unit ||
37 | self::SECOND === $this->unit
38 | ;
39 | }
40 |
41 | static public function year()
42 | {
43 | return new self(self::YEAR);
44 | }
45 |
46 | static public function month()
47 | {
48 | return new self(self::MONTH);
49 | }
50 |
51 | static public function week()
52 | {
53 | return new self(self::WEEK);
54 | }
55 |
56 | static public function day()
57 | {
58 | return new self(self::DAY);
59 | }
60 |
61 | static public function hour()
62 | {
63 | return new self(self::HOUR);
64 | }
65 |
66 | static public function minute()
67 | {
68 | return new self(self::MINUTE);
69 | }
70 |
71 | static public function second()
72 | {
73 | return new self(self::SECOND);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/HowTo/TimeIntervalTest.php:
--------------------------------------------------------------------------------
1 | markTestIncomplete();
13 | }
14 |
15 | public function testHowToKnowIfATimeIntervalIsBeforeAfterDuringAGivenDateInterval()
16 | {
17 | $this->markTestIncomplete();
18 | }
19 |
20 | public function testHowToKnowIfATimeIntervalIsBeforeAfterDuringAGivenDate()
21 | {
22 | $this->markTestIncomplete();
23 | }
24 |
25 | public function testHowToKnowIfATimeIntervalIsBeforeAfterDuringAGivenDateTime()
26 | {
27 | $this->markTestIncomplete();
28 | }
29 |
30 | public function testHowToTransformATimeIntervalIntoADateIntervalDestroyData()
31 | {
32 | $this->markTestIncomplete();
33 | }
34 |
35 | public function testHowToKnowHowLongATimeIntervalAreInAtLeastSecondsMinutesHoursDaysWeeksYears()
36 | {
37 | $this->markTestIncomplete();
38 | }
39 |
40 | /**
41 | * Use cases:
42 | * - Retrieve from a parameters file a time interval in its string represention.
43 | */
44 | public function testHowToTransformStringRepresentationOfTimeIntervalIntoAnObject()
45 | {
46 | $intervalInString = '2013-01-01 04:00,2013-02-02 06:00';
47 | list($begin, $end) = explode(',', $intervalInString);
48 | $interval = TimeIntervalFactory::create($begin, $end);
49 |
50 | $this->assertInstanceOf('Ddd\Time\Model\TimeInterval', $interval);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/Strategy/BaseStrategy.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | class BaseStrategy implements StrategyInterface
14 | {
15 | /**
16 | * {@inheritdoc}
17 | */
18 | public function add(EventInterface $newEvent, array $events)
19 | {
20 | $index = 0;
21 | foreach ($events as $event) {
22 | if ($newEvent->getInterval()->isBefore($event->getInterval())) {
23 | array_splice($events, $index, 0, array($newEvent));
24 |
25 | return $events;
26 | }
27 | $index ++;
28 | }
29 | $events[] = $newEvent;
30 |
31 | return $events;
32 | }
33 |
34 | /**
35 | * {@inheritdoc}
36 | */
37 | public function remove(EventInterface $removedEvent, array $events)
38 | {
39 | $index = 0;
40 | foreach ($events as $event) {
41 | if ($removedEvent->isEquals($event)) {
42 | array_splice($events, $index, 1);
43 | } else {
44 | $index ++;
45 | }
46 | }
47 |
48 | return $events;
49 | }
50 |
51 | /**
52 | * {@inheritdoc}
53 | */
54 | public function update(EventInterface $originalEvent, EventInterface $updatedEvent, array $events)
55 | {
56 | $events = $this->add($updatedEvent, $events);
57 |
58 | try {
59 | $events = $this->remove($originalEvent, $events);
60 | } catch (CalendarExceptionInterface $exception) {
61 | $this->remove($updatedEvent, $events);
62 |
63 | throw $exception;
64 | }
65 |
66 | return $events;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/Infra/Mailer/SwiftMailer.php:
--------------------------------------------------------------------------------
1 | mailer = $mailer;
18 | }
19 |
20 | public function send(Mail $mail)
21 | {
22 | $swiftMessage = $this->transform($mail);
23 |
24 | $failedRecipients = array();
25 | $this->mailer->send($swiftMessage, $failedRecipients);
26 | $this->message = $swiftMessage;
27 |
28 | $contacts = array();
29 | foreach ($failedRecipients as $recipient) {
30 | $contacts[] = new Contact($recipient);
31 | }
32 |
33 | return $contacts;
34 | }
35 |
36 | private function transform(Mail $mail)
37 | {
38 | $recipients = array();
39 | foreach ($mail->getRecipients() as $contact) {
40 | $recipients[$contact->getEmail()] = $contact->getName();
41 | }
42 |
43 | $message = \Swift_Message::newInstance()
44 | ->setCharset($mail->getCharset())
45 | ->setFrom(array($mail->getFrom()->getEmail() => $mail->getFrom()->getName()))
46 | ->setTo($recipients)
47 | ->setSubject($mail->getSubject())
48 | ->setBody($mail->getBody())
49 | ;
50 |
51 | $contentType = ($mail instanceof TextMail) ? 'text/plain' : 'text/html';
52 | $message->setContentType($contentType);
53 |
54 | return $message;
55 | }
56 |
57 | /**
58 | * Use this method only for testing purpose.
59 | *
60 | * @return Swift_Message
61 | */
62 | public function getSentMessage()
63 | {
64 | return $this->message;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/Infra/Mailer/AmazonSesMailer.php:
--------------------------------------------------------------------------------
1 | mailer = $mailer;
19 | }
20 |
21 | public function send(Mail $mail)
22 | {
23 | $amazonSesMessage = $this->transform($mail);
24 |
25 | $this->mailer->getCommand('SendEmail', $amazonSesMessage)->execute();
26 | $this->message = $amazonSesMessage;
27 | }
28 |
29 | private function transform(Mail $mail)
30 | {
31 | $recipients = array();
32 | foreach ($mail->getRecipients() as $contact) {
33 | $recipients[$contact->getEmail()] = $contact->getName();
34 | }
35 |
36 | $message = array(
37 | 'Source' => $mail->getFrom()->toString(),
38 | 'Destination' => array(
39 | 'ToAddresses' => array_keys($recipients)
40 | ),
41 | 'Message' => array(
42 | 'Subject' => array(
43 | 'Data' => $mail->getSubject(),
44 | 'Charset' => $mail->getCharset(),
45 | ),
46 | 'Body' => array(
47 | 'Text' => array(
48 | 'Data' => $mail->getBody(),
49 | 'Charset' => $mail->getCharset(),
50 | ),
51 | ),
52 | ),
53 | );
54 |
55 | return $message;
56 | }
57 |
58 | /**
59 | * Use this method only for testing purpose.
60 | *
61 | * @return Array
62 | */
63 | public function getSentMessage()
64 | {
65 | return $this->message;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/TimeInterval.php:
--------------------------------------------------------------------------------
1 | begin = $begin;
13 | $this->end = $end;
14 | }
15 |
16 | public function isEquals(TimeInterval $interval)
17 | {
18 | return
19 | $this->begin->isEquals($interval->getBegin()) &&
20 | $this->end->isEquals($interval->getEnd())
21 | ;
22 | }
23 |
24 | public function isBefore(IntervalInterface $interval)
25 | {
26 | return $interval->getEnd()->isAfter($this->getBegin()) && $interval->getBegin()->isAfter($this->getEnd());
27 | }
28 |
29 | public function isAfter(IntervalInterface $interval)
30 | {
31 | return $this->begin->isAfter($interval->getEnd());
32 | }
33 |
34 | public function isDuring(IntervalInterface $interval)
35 | {
36 | return !$this->isBefore($interval) && !$this->isAfter($interval);
37 | }
38 |
39 | public function isPartiallyBefore(IntervalInterface $interval)
40 | {
41 | throw new \Exception('Not implemented');
42 | }
43 |
44 | public function isPartiallyAfter(IntervalInterface $interval)
45 | {
46 | throw new \Exception('Not implemented');
47 | }
48 |
49 | public function getBegin()
50 | {
51 | return $this->begin;
52 | }
53 |
54 | public function getEnd()
55 | {
56 | return $this->end;
57 | }
58 |
59 | public function getLength()
60 | {
61 | $begin = $this->begin->toDateTime();
62 | $end = $this->end->toDateTime();
63 | $diff = $begin->diff($end);
64 |
65 | return new Duration($diff->format('%H'), TimeUnit::hour());
66 | }
67 |
68 | public function isInclude(IntervalInterface $other)
69 | {
70 | throw new \Exception('Not yet implemented.');
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Tests/HowTo/CalendarTest.php:
--------------------------------------------------------------------------------
1 | calendar = $repository->load();
20 | }
21 |
22 | public function testHowToLoadEventsFromDatastore()
23 | {
24 | $this->markTestIncomplete();
25 | }
26 |
27 | public function testHowToRetrieveAllMyAppointments()
28 | {
29 | $this->assertSame('Doctor Smith\'s appointments', $this->calendar->getTitle());
30 | $this->assertCount(3, $this->calendar);
31 | }
32 |
33 | public function testHowToRetrieveMyAppointmentsForToday()
34 | {
35 | $today = DateIntervalFactory::create('2012-01-01', '2012-01-01');
36 | $this->assertCount(1, $this->calendar->between(TimeIntervalFactory::fromDateInterval($today)));
37 | }
38 |
39 | public function testHowToRetrieveAppointmentsAfterADate()
40 | {
41 | $today = new TimePoint(2012, 1, 1, 10, 0);
42 | $this->calendar->setCursor($today);
43 | $this->assertSame(2, $this->calendar->countRemaining());
44 | }
45 |
46 | public function testHowToRetrieveMyAppointmentsForCurrentWeek()
47 | {
48 | $week = DateIntervalFactory::create('2012-01-01', '2012-01-07');
49 | $this->assertCount(2, $this->calendar->between(TimeIntervalFactory::fromDateInterval($week)));
50 | }
51 |
52 | public function testHowToAddNewAppointment()
53 | {
54 | $event = new Event(TimeIntervalFactory::create('2012-01-01 17:00', '2012-01-01 18:00'));
55 | $this->calendar->add($event);
56 | $this->assertCount(4, $this->calendar);
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Exception/CalendarEventException.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class CalendarEventException extends \LogicException implements CalendarExceptionInterface
13 | {
14 | /**
15 | * @var EventInterface
16 | */
17 | private $event;
18 |
19 | /**
20 | * @param EventInterface $event
21 | *
22 | * @return CalendarEventException
23 | */
24 | public static function addWhileFrozen(EventInterface $event)
25 | {
26 | return new self($event, 'Cannot add event to frozen calendar.');
27 | }
28 |
29 | /**
30 | * @param EventInterface $event
31 | *
32 | * @return CalendarEventException
33 | */
34 | public static function removeWhileFrozen(EventInterface $event)
35 | {
36 | return new self($event, 'Cannot remove event from frozen calendar.');
37 | }
38 |
39 |
40 | /**
41 | * @param EventInterface $event
42 | *
43 | * @return CalendarEventException
44 | */
45 | public static function updateWhileFrozen(EventInterface $event)
46 | {
47 | return new self($event, 'Cannot update event from frozen calendar.');
48 | }
49 |
50 | /**
51 | * @param EventInterface $event
52 | *
53 | * @return CalendarEventException
54 | */
55 | public static function eventOverlap(EventInterface $event)
56 | {
57 | return new self($event, 'Events overlap detected.');
58 | }
59 |
60 | /**
61 | * @param EventInterface $event
62 | * @param int $message
63 | */
64 | public function __construct(EventInterface $event, $message)
65 | {
66 | parent::__construct($message);
67 | $this->event = $event;
68 | }
69 |
70 | /**
71 | * @return EventInterface
72 | */
73 | public function getEvent()
74 | {
75 | return $this->event;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/Model/Mail.php:
--------------------------------------------------------------------------------
1 | from = $from;
21 | $this->charset = 'utf-8';
22 | }
23 |
24 | public function compose($subject, $body)
25 | {
26 | $this->subject = $subject;
27 | $this->body = $body;
28 |
29 | return $this;
30 | }
31 |
32 | public function addRecipient(Contact $recipient)
33 | {
34 | $this->recipients[] = $recipient;
35 |
36 | return $this;
37 | }
38 |
39 | public function send(MailerInterface $mailer)
40 | {
41 | if (null === $this->subject && null === $this->body) {
42 | throw new MailNotComposedException();
43 | }
44 |
45 | if (0 === count($this->recipients)) {
46 | throw new MailWithoutRecipientException();
47 | }
48 |
49 | $this->failedRecipients = $mailer->send($this);
50 | if (0 === count($this->failedRecipients)) {
51 | $this->sent = true;
52 | }
53 | }
54 |
55 | public function isSent()
56 | {
57 | return $this->sent;
58 | }
59 |
60 | public function getRecipients()
61 | {
62 | return $this->recipients;
63 | }
64 |
65 | public function getFrom()
66 | {
67 | return $this->from;
68 | }
69 |
70 | public function getFailedRecipients()
71 | {
72 | return $this->failedRecipients;
73 | }
74 |
75 | public function getSubject()
76 | {
77 | return $this->subject;
78 | }
79 |
80 | public function getBody()
81 | {
82 | return $this->body;
83 | }
84 |
85 | public function getCharset()
86 | {
87 | return $this->charset;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Model/DateIntervalTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(new Duration(0, TimeUnit::day()), $interval->getDuration());
19 |
20 | $interval = new DateInterval(new Date(2012, 01, 01), new Date(2012, 01, 03));
21 | $this->assertEquals(new Duration(2, TimeUnit::day()), $interval->getDuration());
22 | }
23 |
24 | public function testNextEquals()
25 | {
26 | $startDate = new Date(2012, 01, 01);
27 | $endDate = new Date(2012, 01, 03);
28 |
29 | $interval = new DateInterval($startDate, $endDate);
30 | $this->assertEquals($startDate, $interval->getBegin());
31 | $this->assertEquals(new Date(2012, 01, 02), $interval->getBegin()->next());
32 | $this->assertEquals(new Date(2012, 01, 03), $interval->getBegin()->next()->next());
33 |
34 | $this->assertFalse($endDate->isEquals($interval->getBegin()));
35 | $this->assertFalse($endDate->isEquals($interval->getBegin()->next()));
36 | $this->assertTrue($endDate->isEquals($interval->getBegin()->next()->next()));
37 | }
38 |
39 | public function testIsInclude()
40 | {
41 | $interval = DateIntervalFactory::create('2013-01-10', '2013-01-20');
42 |
43 | $this->assertTrue($interval->isInclude(DateIntervalFactory::create('2013-01-13', '2013-01-14')));
44 | $this->assertTrue($interval->isInclude(DateIntervalFactory::create('2013-01-13', '2013-01-15')));
45 | $this->assertTrue($interval->isInclude(DateIntervalFactory::create('2013-01-14', '2013-01-15')));
46 | $this->assertTrue($interval->isInclude(TimeIntervalFactory::create('2013-01-13 01:00', '2013-01-14 18:30')));
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/Strategy/PersistenceStrategy.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | class PersistenceStrategyDecorator implements StrategyInterface
16 | {
17 | /**
18 | * @var CalendarInterface
19 | */
20 | private $calendar;
21 |
22 | /**
23 | * @var StrategyInterface
24 | */
25 | private $innerStrategy;
26 |
27 | /**
28 | * @var CalendarPersisterInterface
29 | */
30 | private $persister;
31 |
32 | /**
33 | * @param CalendarInterface $calendar
34 | * @param StrategyInterface $innerStrategy
35 | * @param CalendarPersisterInterface $persister
36 | */
37 | public function __construct(CalendarInterface $calendar, StrategyInterface $innerStrategy, CalendarPersisterInterface $persister)
38 | {
39 | $this->calendar = $calendar;
40 | $this->innerStrategy = $innerStrategy;
41 | $this->persister = $persister;
42 | }
43 |
44 | /**
45 | * {@inheritdoc}
46 | */
47 | public function add(EventInterface $newEvent, array $events)
48 | {
49 | $result = $this->innerStrategy->add($newEvent, $events);
50 | $this->persister->persist($this->calendar);
51 |
52 | return $result;
53 | }
54 |
55 | /**
56 | * {@inheritdoc}
57 | */
58 | public function remove(EventInterface $removedEvent, array $events)
59 | {
60 | $result = $this->innerStrategy->remove($removedEvent, $events);
61 | $this->persister->persist($this->calendar);
62 |
63 | return $result;
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | public function update(EventInterface $originalEvent, EventInterface $updatedEvent, array $events)
70 | {
71 | return $this->innerStrategy->update($originalEvent, $updatedEvent, $events);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/FixedDateInterval.php:
--------------------------------------------------------------------------------
1 | begin = $begin;
13 | $this->end = $end;
14 | }
15 |
16 | /**
17 | * Gets the begin value
18 | *
19 | * @return Date
20 | */
21 | public function getBegin()
22 | {
23 | return $this->begin;
24 | }
25 |
26 | /**
27 | * Gets the end value
28 | *
29 | * @return Date
30 | */
31 | public function getEnd()
32 | {
33 | return $this->end;
34 | }
35 |
36 | public function isInclude(IntervalInterface $other)
37 | {
38 | if ($other instanceof TimeInterval) {
39 | $otherBegin = $other->getBegin()->getDate();
40 | $otherEnd = $other->getEnd()->getDate();
41 | } else {
42 | $otherBegin = $other->getBegin();
43 | $otherEnd = $other->getEnd();
44 | }
45 |
46 | return
47 | ($this->begin->isBefore($otherBegin) || $this->begin->isEquals($otherBegin)) &&
48 | ($this->end->isAfter($otherEnd) || $this->end->isEquals($otherEnd))
49 | ;
50 | }
51 |
52 | /**
53 | * @param IntervalInterface $other
54 | * @return bool
55 | */
56 | public function isBefore(IntervalInterface $other)
57 | {
58 | throw new \Exception('Not implemented');
59 | }
60 |
61 | /**
62 | * @param IntervalInterface $other
63 | * @return bool
64 | */
65 | public function isAfter(IntervalInterface $other)
66 | {
67 | throw new \Exception('Not implemented');
68 | }
69 |
70 | /**
71 | * @param IntervalInterface $other
72 | * @return bool
73 | */
74 | public function isDuring(IntervalInterface $other)
75 | {
76 | throw new \Exception('Not implemented');
77 | }
78 |
79 | public function isPartiallyBefore(IntervalInterface $interval)
80 | {
81 | throw new \Exception('Not implemented');
82 | }
83 |
84 | public function isPartiallyAfter(IntervalInterface $interval)
85 | {
86 | throw new \Exception('Not implemented');
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/TimeOfDay.php:
--------------------------------------------------------------------------------
1 | hour = (int)$hour;
14 | $this->minutes = (int)$minutes;
15 | $this->seconds = (int)$seconds;
16 | }
17 |
18 | public function isEquals(TimeOfDay $other)
19 | {
20 | return
21 | $this->hour === $other->getHour() &&
22 | $this->minutes === $other->getMinutes() &&
23 | $this->seconds === $other->getSeconds()
24 | ;
25 | }
26 |
27 | public function isBefore(TimeOfDay $other)
28 | {
29 | return
30 | false === $this->isEquals($other) &&
31 | false === $this->isAfter($other);
32 | }
33 |
34 | public function isAfter(TimeOfDay $other)
35 | {
36 | return
37 | $this->hour > $other->getHour() ||
38 | ($this->hour === $other->getHour() && $this->minutes > $other->getMinutes()) ||
39 | ($this->hour === $other->getHour() && $this->minutes === $other->getMinutes() && $this->seconds > $other->getSeconds())
40 | ;
41 | }
42 |
43 | public function isAnteMeridian()
44 | {
45 | return $this->hour < 12;
46 | }
47 |
48 | public function isPostMeridian()
49 | {
50 | return false === $this->isAnteMeridian();
51 | }
52 |
53 | public function __toString()
54 | {
55 | $hour = ($this->hour < 10) ? '0'.$this->hour : $this->hour;
56 | $minutes = ($this->minutes < 10) ? '0'.$this->minutes : $this->minutes;
57 |
58 | return $hour.':'.$minutes;
59 | }
60 |
61 | /**
62 | * Gets the value of hour
63 | *
64 | * @return int
65 | */
66 | public function getHour()
67 | {
68 | return $this->hour;
69 | }
70 |
71 | /**
72 | * Gets the value of minutes
73 | *
74 | * @return int
75 | */
76 | public function getMinutes()
77 | {
78 | return $this->minutes;
79 | }
80 |
81 | /**
82 | * Gets the value of minutes
83 | *
84 | * @return int
85 | */
86 | public function getSeconds()
87 | {
88 | return $this->seconds;
89 | }
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/README.md:
--------------------------------------------------------------------------------
1 | Slug: an agnostic slug generator
2 | ================================
3 |
4 | **Slug** is a component which generates slugs easily whatever persistence
5 | mecanism you use (Propel2, Doctrine2, custom ORM...).
6 |
7 | To generate a slug of a string there is always two 2 steps:
8 |
9 | - The transliteration step which converts a given string from any writing system
10 | (French, Deutsh, Greek, Arabic...) into its ASCII representation.
11 | - The slug generation step which basically separates each word and field by a custom delimiter.
12 |
13 | Therefore **Slug** component has 2 services: `TransliteratorInterface` and `SlugGeneratorInterface`. Each of these services
14 | can have multiple implementations:
15 |
16 | - `LatinTransliterator`: Transliterate a string written in any Latin
17 | alphabet (French, Deutsh, Spanish...) into its ASCII equivalent.
18 | - `DefaultSlugGenerator`: Customize the word and field separator.
19 | - `PatternSlugGenerator`: Complete customization of slug generation.
20 |
21 | Installation
22 | ------------
23 |
24 | Using Composer, just require the `ddd/components` package:
25 |
26 | ``` javascript
27 | {
28 | "require": {
29 | "ddd/components": "dev-master"
30 | }
31 | }
32 | ```
33 |
34 | Usage
35 | -----
36 |
37 | To be able to slugify an entity or model, you just have to implement the `SluggableInterface`:
38 |
39 | ``` php
40 | slug = $slugifier->slugify(array($this->createdAt->format('Y'), $this->title));
54 | }
55 |
56 | // other methods...
57 | }
58 | ```
59 |
60 | Then you just have to call the `slugify` method to generate the slug:
61 |
62 | ``` php
63 | use Ddd\Slug\Infra\SlugGenerator\DefaultSlugGenerator;
64 | use Ddd\Slug\Infra\Transliterator\LatinTransliterator;
65 |
66 | $article = new Article();
67 | $article->setTitle('Hello world!');
68 | $article->slugify(new DefaultSlugGenerator(array(new LatinTransliterator())));
69 |
70 | echo $article->getSlug(); // writes "2013-hello-world"
71 | ```
72 |
73 | Credits
74 | -------
75 |
76 | - Joseph Rouff
77 | - Jean-François Simon
78 |
79 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Infra/Transliterator/TransliteratorCollection.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class TransliteratorCollection
11 | {
12 | /**
13 | * @var TransliteratorInterface[]
14 | */
15 | private $transliterators = array();
16 |
17 | /**
18 | * @param TransliteratorInterface[] $transliterators
19 | */
20 | public function __construct(array $transliterators)
21 | {
22 | foreach ($transliterators as $transliterator) {
23 | $this->add($transliterator);
24 | }
25 | }
26 |
27 | /**
28 | * @param TransliteratorInterface $transliterator
29 | *
30 | * @return TransliteratorCollection
31 | */
32 | public function add(TransliteratorInterface $transliterator)
33 | {
34 | $this->transliterators[$transliterator->getName()] = $transliterator;
35 |
36 | return $this;
37 | }
38 |
39 | /**
40 | * Transliterates string with named transliterator.
41 | *
42 | * @param string $name Transliterator name
43 | * @param string $string String to transliterate
44 | *
45 | * @throws \InvalidArgumentException If transliterator not found
46 | *
47 | * @return string Transliterated string
48 | */
49 | public function transliterate($name, $string)
50 | {
51 | if (!isset($this->transliterators[$name])) {
52 | throw new \InvalidArgumentException(sprintf(
53 | 'Unknwon transliterator "%s", known ones are "%s".',
54 | $name,
55 | implode('", "', array_keys($this->transliterators))
56 | ));
57 | }
58 |
59 | return $this->transliterators[$name]->transliterate($string);
60 | }
61 |
62 | /**
63 | * @param string $name
64 | *
65 | * @return boolean
66 | */
67 | public function has($name)
68 | {
69 | return isset($this->transliterators[$name]);
70 | }
71 |
72 | /**
73 | * @param string $name
74 | *
75 | * @return TransliteratorInterface
76 | *
77 | * @throws \InvalidArgumentException
78 | */
79 | public function get($name)
80 | {
81 | if (!isset($this->transliterators[$name])) {
82 | throw new \InvalidArgumentException('Transliterator "'.$name.'" does not exist.');
83 | }
84 |
85 | return $this->transliterators[$name];
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Model/TimePointTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(new TimePoint(2015, 1, 1, 9, 30), $point->plus(new Duration(3, TimeUnit::year())));
18 | $this->assertEquals(new TimePoint(2012, 5, 1, 9, 30), $point->plus(new Duration(4, TimeUnit::month())));
19 | $this->assertEquals(new TimePoint(2012, 1, 3, 9, 30), $point->plus(new Duration(2, TimeUnit::day())));
20 | $this->assertEquals(new TimePoint(2012, 1, 1, 12, 30), $point->plus(new Duration(3, TimeUnit::hour())));
21 | $this->assertEquals(new TimePoint(2012, 1, 1, 10, 0), $point->plus(new Duration(30, TimeUnit::minute())));
22 | }
23 |
24 | public function testMinus()
25 | {
26 | $point = new TimePoint(2012, 1, 1, 9, 30);
27 |
28 | $this->assertEquals(new TimePoint(2009, 1, 1, 9, 30), $point->minus(new Duration(3, TimeUnit::year())));
29 | $this->assertEquals(new TimePoint(2011, 9, 1, 9, 30), $point->minus(new Duration(4, TimeUnit::month())));
30 | $this->assertEquals(new TimePoint(2011, 12, 30, 9, 30), $point->minus(new Duration(2, TimeUnit::day())));
31 | $this->assertEquals(new TimePoint(2012, 1, 1, 6, 30), $point->minus(new Duration(3, TimeUnit::hour())));
32 | $this->assertEquals(new TimePoint(2012, 1, 1, 9, 0), $point->minus(new Duration(30, TimeUnit::minute())));
33 | }
34 |
35 | public function testUntilDuring()
36 | {
37 | $point = new TimePoint(2012, 1, 1, 9, 30);
38 |
39 | $expectedInterval = new TimeInterval(new TimePoint(2012, 1, 1, 9, 30), new TimePoint(2012, 1, 1, 13, 30));
40 | $this->assertTrue($expectedInterval->isEquals($point->during(new Duration(4, TimeUnit::hour()))));
41 | $this->assertTrue($expectedInterval->isEquals($point->until(new TimePoint(2012, 1, 1, 13, 30))));
42 | }
43 |
44 | public function testIsAfter()
45 | {
46 | $point = new TimePoint(2012, 2, 1, 1, 0, 30);
47 |
48 | // second
49 | $this->assertTrue($point->isAfter(new TimePoint(2012, 2, 1, 1, 0, 29)));
50 | $this->assertFalse($point->isAfter(new TimePoint(2012, 2, 1, 1, 0, 30)));
51 | $this->assertFalse($point->isAfter(new TimePoint(2012, 2, 1, 1, 0, 31)));
52 | }
53 |
54 | public function testToTimePoint()
55 | {
56 | $point = new TimePoint(2013, 1, 1, 2, 30);
57 | $interval = $point->toTimeInterval();
58 |
59 | $this->assertInstanceOf('Ddd\Time\Model\TimeInterval', $interval);
60 | $this->assertEquals(new TimeInterval($point, $point), $interval);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Infra/SlugGenerator/DefaultSlugGenerator.php:
--------------------------------------------------------------------------------
1 |
12 | * @author Jean-François Simon
13 | */
14 | class DefaultSlugGenerator implements SlugGeneratorInterface
15 | {
16 | const REPLACED_CHARS = '~[^a-z0-9]~i';
17 |
18 | /**
19 | * @var TransliteratorCollection
20 | */
21 | private $transliterators;
22 |
23 | /**
24 | * @var array
25 | */
26 | private $defaultOptions;
27 |
28 | /**
29 | * @param TransliteratorCollection $transliterators
30 | * @param array $defaultOptions
31 | */
32 | public function __construct(TransliteratorCollection $transliterators, array $defaultOptions)
33 | {
34 | $this->transliterators = $transliterators;
35 | $this->defaultOptions = array_merge(array(
36 | 'word_separator' => '-',
37 | 'field_separator' => '-',
38 | 'transliterator' => 'latin',
39 | ), $defaultOptions);
40 | }
41 |
42 | /**
43 | * {@inheritdoc}
44 | */
45 | public function slugify(array $fieldValues, array $options = array())
46 | {
47 | $options = array_merge($this->defaultOptions, $options);
48 |
49 | if (!$this->validateOptions($options)) {
50 | throw new \InvalidArgumentException('Some of given options are not expected');
51 | }
52 |
53 | $stringToSlugify = $this->transliterators->transliterate($options['transliterator'], implode($options['field_separator'], $fieldValues));
54 | $slug = $this->replaceUnwantedChars($stringToSlugify, $options['word_separator']);
55 | $slug = $this->removeDuplicateWordSeparators($slug, $options['word_separator']);
56 |
57 | return trim(strtolower($slug), $options['word_separator']);
58 | }
59 |
60 | /**
61 | * @param array $options
62 | *
63 | * @return bool
64 | */
65 | public function validateOptions(array $options)
66 | {
67 | return true;
68 | }
69 |
70 | /**
71 | * @param string $stringToSlugify
72 | * @param string $wordSeparator
73 | *
74 | * @return string
75 | */
76 | private function replaceUnwantedChars($stringToSlugify, $wordSeparator)
77 | {
78 | return preg_replace(self::REPLACED_CHARS, $wordSeparator, $stringToSlugify);
79 | }
80 |
81 | /**
82 | * @param string $slug
83 | * @param string $wordSeparator
84 | *
85 | * @return string
86 | */
87 | private function removeDuplicateWordSeparators($slug, $wordSeparator)
88 | {
89 | return preg_replace('~['.preg_quote($wordSeparator).']+~', $wordSeparator, $slug);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Model/FixedDateTest.php:
--------------------------------------------------------------------------------
1 | assertFalse($christmasDay->isAfter(new Date(2013, 12, 25)));
15 | $this->assertFalse($christmasDay->isAfter(new Date(2000, 12, 25)));
16 | $this->assertTrue($christmasDay->isAfter(new Date(2013, 12, 24)));
17 | $this->assertTrue($christmasDay->isAfter(new Date(2000, 12, 24)));
18 | $this->assertFalse($christmasDay->isAfter(new Date(2013, 12, 26)));
19 | $this->assertFalse($christmasDay->isAfter(new Date(2000, 12, 26)));
20 | }
21 |
22 | public function testIsAfterWhenMonthNotGiven()
23 | {
24 | $day25 = new FixedDate(null, 25);
25 | $this->assertTrue($day25->isAfter(new Date(2013, 12, 24)));
26 | $this->assertTrue($day25->isAfter(new Date(2013, 1, 24)));
27 | $this->assertTrue($day25->isAfter(new Date(2000, 5, 24)));
28 | }
29 |
30 | public function testIsBefore()
31 | {
32 | $christmasDay = new FixedDate(12, 25);
33 | $this->assertFalse($christmasDay->isBefore(new Date(2013, 12, 25)));
34 | $this->assertFalse($christmasDay->isBefore(new Date(2000, 12, 25)));
35 | $this->assertFalse($christmasDay->isBefore(new Date(2013, 12, 24)));
36 | $this->assertFalse($christmasDay->isBefore(new Date(2000, 12, 24)));
37 | $this->assertTrue($christmasDay->isBefore(new Date(2013, 12, 26)));
38 | $this->assertTrue($christmasDay->isBefore(new Date(2000, 12, 26)));
39 | }
40 |
41 | public function testIsBeforeWhenMonthNotGiven()
42 | {
43 | $day25 = new FixedDate(null, 25);
44 | $this->assertTrue($day25->isBefore(new Date(2013, 12, 26)));
45 | $this->assertTrue($day25->isBefore(new Date(2013, 1, 26)));
46 | $this->assertTrue($day25->isBefore(new Date(2000, 5, 26)));
47 | }
48 |
49 | public function testIsEquals()
50 | {
51 | $christmasDay = new FixedDate(12, 25);
52 | $this->assertTrue($christmasDay->isEquals(new Date(2013, 12, 25)));
53 | $this->assertTrue($christmasDay->isEquals(new Date(2000, 12, 25)));
54 | $this->assertFalse($christmasDay->isEquals(new Date(2013, 12, 24)));
55 | $this->assertFalse($christmasDay->isEquals(new Date(2000, 12, 24)));
56 | $this->assertFalse($christmasDay->isEquals(new Date(2013, 12, 26)));
57 | $this->assertFalse($christmasDay->isEquals(new Date(2000, 12, 26)));
58 | }
59 |
60 | public function testIsEqualsWhenMonthNotGiven()
61 | {
62 | $day25 = new FixedDate(null, 25);
63 | $this->assertTrue($day25->isEquals(new Date(2013, 12, 25)));
64 | $this->assertTrue($day25->isEquals(new Date(2013, 1, 25)));
65 | $this->assertTrue($day25->isEquals(new Date(2000, 5, 25)));
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/HowTo/DurationTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(new Duration(15840, TimeUnit::minute()), $duration1->toMinutes());
16 | $this->assertEquals(new Duration(950400, TimeUnit::second()), $duration1->toSeconds());
17 | $this->assertEquals(new Duration(72, TimeUnit::hour()), $duration2->toHours());
18 | $this->assertEquals(new Duration(4320, TimeUnit::minute()), $duration2->toMinutes());
19 | $this->assertEquals(new Duration(259200, TimeUnit::second()), $duration2->toSeconds());
20 | }
21 |
22 | public function testHowToKnowHowLongXWeeksInDaysHoursMinutesSeconds()
23 | {
24 | $duration1 = new Duration(1, TimeUnit::week());
25 | $this->assertEquals(new Duration(7, TimeUnit::day()), $duration1->toDays());
26 | $this->assertEquals(new Duration(7*24, TimeUnit::hour()), $duration1->toHours());
27 | $this->assertEquals(new Duration(7*24*60, TimeUnit::minute()), $duration1->toMinutes());
28 | $this->assertEquals(new Duration(7*24*60*60, TimeUnit::second()), $duration1->toSeconds());
29 | }
30 |
31 | public function testHowToKnowHowLongXMonthsInWeeksDaysHoursMinutesSeconds()
32 | {
33 | $duration1 = new Duration(2, TimeUnit::month(), 2013, 2);
34 | $duration2 = new Duration(2, TimeUnit::month(), 2012, 2);
35 |
36 | $this->assertEquals(new Duration(28+31, TimeUnit::day()), $duration1->toDays());
37 | $this->assertEquals(new Duration(29+31, TimeUnit::day()), $duration2->toDays());
38 | $this->assertEquals(new Duration((28+31)*24, TimeUnit::hour()), $duration1->toHours());
39 | $this->assertEquals(new Duration((28+31)*24*60, TimeUnit::minute()), $duration1->toMinutes());
40 | $this->assertEquals(new Duration((28+31)*24*60*60, TimeUnit::second()), $duration1->toSeconds());
41 | }
42 |
43 | public function testHowToKnowHowLongXYearsInMonthsWeeksDaysHoursMinutesSeconds()
44 | {
45 | $duration1 = new Duration(1, TimeUnit::year(), 2013);
46 | $duration2 = new Duration(1, TimeUnit::year(), 2012);
47 |
48 | $this->assertEquals(new Duration(365, TimeUnit::day()), $duration1->toDays());
49 | $this->assertEquals(new Duration(366, TimeUnit::day()), $duration2->toDays());
50 | $this->assertEquals(new Duration(365*24, TimeUnit::hour()), $duration1->toHours());
51 | $this->assertEquals(new Duration(365*24*60, TimeUnit::minute()), $duration1->toMinutes());
52 | $this->assertEquals(new Duration(365*24*60*60, TimeUnit::second()), $duration1->toSeconds());
53 | }
54 |
55 | public function testHowToKnowHowLongAYearsBMonthsCWeeksDDaysInHoursMinutesSeconds()
56 | {
57 | $this->markTestIncomplete();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Ddd/Slug/Tests/AcceptanceTest.php:
--------------------------------------------------------------------------------
1 | defaultSlugGenerator = new DefaultSlugGenerator($transliterators);
24 | $this->passthruSlugGenerator = new PassthruSlugGenerator();
25 | }
26 |
27 | public function testEntityPassthruSlugification()
28 | {
29 | $title = 'Héllo slugifier!';
30 | $article = new InMemoryArticle();
31 | $article->setTitle($title);
32 | $article->slugify($this->passthruSlugGenerator);
33 | $this->assertEquals($title, $article->getSlug());
34 | }
35 |
36 | /** @dataProvider Ddd\Slug\Tests\AcceptanceDataProvider::getEntityAsciiTextSlugificationData */
37 | public function testEntityAsciiTextSlugification($title, $slug)
38 | {
39 | $article = new InMemoryArticle();
40 | $article->setTitle($title);
41 | $article->slugify($this->defaultSlugGenerator);
42 | $this->assertEquals($slug, $article->getSlug());
43 | }
44 |
45 | /** @dataProvider Ddd\Slug\Tests\AcceptanceDataProvider::getEntityLatinTransliteratedSlugificationData */
46 | public function testEntityLatinTransliteratedSlugification($title, $slug)
47 | {
48 | $article = new InMemoryArticle();
49 | $article->setTitle($title);
50 | $article->slugify($this->defaultSlugGenerator);
51 | $this->assertEquals($slug, $article->getSlug());
52 | }
53 |
54 | public function testICouldUseSlugifyWithDoctrineOrm()
55 | {
56 | TestDatabase::backup();
57 |
58 | // Doctrine setup
59 | $params = array('driver' => 'pdo_sqlite', 'path' => __DIR__.'/Resources/db.sqlite');
60 | $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__.'/Fixtures'), true);
61 | $em1 = EntityManager::create($params, $config);
62 | $em2 = EntityManager::create($params, $config);
63 |
64 | // Create a new entity which should be slugified
65 | $persistedArticle = new DoctrineArticle();
66 | $persistedArticle->setTitle('Hello world!');
67 | $persistedArticle->slugify($this->defaultSlugGenerator);
68 |
69 | // Store into database slugified entity
70 | $em1->persist($persistedArticle);
71 | $em1->flush();
72 |
73 | // Retrieve entity from database
74 | $loadedArticle = $em2->find('Ddd\Slug\Tests\Fixtures\DoctrineArticle', $persistedArticle->getId());
75 | $this->assertEquals('hello-world', $loadedArticle->getSlug());
76 |
77 | TestDatabase::restore();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/Tests/Acceptance/BasicMailTest.php:
--------------------------------------------------------------------------------
1 | mail = new TextMail(new Contact('rouffj@gmail.com'));
18 | }
19 |
20 | public function testWhenNewMail()
21 | {
22 | $mail = new TextMail($from = new Contact('foo@bar.com'));
23 |
24 | $this->assertEquals('utf-8', $mail->getCharset());
25 | $this->assertNull($mail->getSubject());
26 | $this->assertNull($mail->getBody());
27 | $this->assertEquals($from, $mail->getFrom());
28 | $this->assertFalse($mail->isSent());
29 | $this->assertEquals(array(), $mail->getFailedRecipients());
30 | $this->assertEquals(array(), $mail->getRecipients());
31 | }
32 |
33 | public function testSendWhenMailNotComposed()
34 | {
35 | try {
36 | $this->mail->send(new NullMailer);
37 | $this->fail('An exception should be thrown because neither subject nor body filled in');
38 | } catch(MailNotComposedException $e) {
39 | $this->assertTrue(true);
40 | }
41 | }
42 |
43 | public function testSendWhenMailComposedWithNullValue()
44 | {
45 | $this->mail->compose(null, null);
46 |
47 | try {
48 | $this->mail->send(new NullMailer);
49 | $this->fail('An exception should be thrown because neither subject nor body filled in');
50 | } catch(MailNotComposedException $e) {
51 | $this->assertTrue(true);
52 | }
53 | }
54 |
55 | public function testComposeWhenTextGiven()
56 | {
57 | $this->mail->compose('My subject', 'My body');
58 |
59 | $this->assertEquals('My subject', $this->mail->getSubject());
60 | $this->assertEquals('My body', $this->mail->getBody());
61 | }
62 |
63 | public function testSendWhenMailWithoutRecipient()
64 | {
65 | $this->mail->compose('My subject', null);
66 |
67 | try {
68 | $this->mail->send(new NullMailer);
69 | $this->fail('An exception should be thrown because no recipient added');
70 | } catch(MailWithoutRecipientException $e) {
71 | $this->assertTrue(true);
72 | }
73 | }
74 |
75 | public function testSendWhenMailSent()
76 | {
77 | $this->mail->compose('My subject', null);
78 | $this->mail->addRecipient(new Contact('rouffj@gmail.com'));
79 |
80 | $this->mail->send(new NullMailer);
81 |
82 | $this->assertEquals(array(), $this->mail->getFailedRecipients());
83 | $this->assertEquals(true, $this->mail->isSent());
84 | }
85 |
86 | public function testSendWhenMailNotSent()
87 | {
88 | $this->mail->compose('My subject', null);
89 | $this->mail->addRecipient($contact = new Contact('rouffj@gmail.com'));
90 |
91 | $this->mail->send(new NullMailer(false));
92 |
93 | $this->assertEquals(array($contact), $this->mail->getFailedRecipients());
94 | $this->assertEquals(false, $this->mail->isSent());
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/Ddd/Mail/README.md:
--------------------------------------------------------------------------------
1 | # Mail #
2 |
3 |
4 | **Mail** is a component which allow to create/send email easily whatever mailer
5 | mecanism you use (SwiftMailer...).
6 |
7 | ## Installation ##
8 |
9 | Using Composer, just require the `ddd/components` package:
10 |
11 | ``` javascript
12 | {
13 | "require": {
14 | "ddd/components": "dev-master"
15 | }
16 | }
17 | ```
18 |
19 | ## Usage ##
20 |
21 | ### 1. Prepare your email ###
22 |
23 | #### Method A ####
24 |
25 | ```php
26 | compose('[Github] Payment receipt', 'Here my body formatted in Text format')
36 | ->addRecipient(new Contact('customer1@gmail.com'))
37 | ->addRecipient(new Contact('customer2@gmail.com', 'Customer 2'))
38 | ;
39 | ```
40 |
41 | #### Method B ####
42 |
43 | ```php
44 | compose('[Github] Payment receipt', 'Here my body formatted in Text format')
52 | ->addRecipients(array(
53 | 'customer1@gmail.com',
54 | 'customer2@gmail.com' => 'Customer 2'
55 | ))
56 | ->getTextMail()
57 | ;
58 | ```
59 |
60 | ### 2. Send it###
61 |
62 | With `Mail` you can send your emails with the mailer of your choice (SwiftMailer, Amazon SES, Compain monitor...):
63 |
64 | ```php
65 | $mail->send(new SwiftMailer($container->get('swift_mailer'))); // Send email with SwiftMailer.
66 | $mail->send(new AmazonSesMailer($container->get('aws.ses.client'))); // Send same email with Amazon SES.
67 | ```
68 |
69 | Icebox
70 | ------
71 |
72 | * [x] As a user, I should be able to create a sendable basic email with very simple API.
73 | * [x] As a user, I should be able to send basic `TextMail` with SwiftMailer as `MailerInterface` implementation.
74 | * [x] As a user, I should be able to send basic `TextMail` with "Amazon SES" as `MailerInterface` implementation.
75 | * [ ][Chore] As a user, I'm expecting when any error occured, a `MailerException` should be thrown whatever implementation used.
76 | * [x] As a user, I should be able to create a mail without knowing any domain object.
77 | * [ ] As a user, I could give as recipient a group of contacts that will enable "Newsletter" mode.
78 | * [ ] As a user, I could be able to send basic `HtmlEmail` with SwiftMailer.
79 | * [ ] As a user, I could add attachments to `HtmlEmail` AND `TextEmail`.
80 | * [ ] As a user, I could give copy carbon recipient.
81 | * [ ] As a user, I could give blind copy carbon recipient.
82 | * [ ] As a user, a contact should always be valid.
83 | * [ ] As a user, I should be able to change default UTF-8 encoding.
84 | * [ ] As a user, I should be able to send basic `TextMail` with "Compaign Monitor" as `MailerInterface` implementation.
85 | * [ ] As a user, when I put HTML content as body in a `TextMail` the content should be strip of all HTML tags.
86 | * [ ] As a user, when I put HTML content as body in an `HtmlMail` the plain text version should be generated automatically.
87 | * [ ] As a Amazon SES user, I should be able to put special characters in headers (To:, From: etc.).
88 |
89 | Credits
90 | -------
91 |
92 | - Joseph Rouff
93 |
94 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Model/DurationTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(780, $duration->toSeconds()->getValue());
15 |
16 | $duration = new Duration(2, TimeUnit::hour());
17 | $this->assertEquals(7200, $duration->toSeconds()->getValue());
18 |
19 | $duration = new Duration(5, TimeUnit::day());
20 | $this->assertEquals(432000, $duration->toSeconds()->getValue());
21 |
22 | $duration = new Duration(1, TimeUnit::week());
23 | $this->assertEquals(604800, $duration->toSeconds()->getValue());
24 |
25 | try {
26 | $duration = new Duration(2, TimeUnit::month());
27 | $duration->toSeconds();
28 | $this->assertEquals(true, false);
29 | } catch (\LogicException $e) {
30 | $this->assertEquals(true, true);
31 | }
32 |
33 | }
34 |
35 | public function testToMinutes()
36 | {
37 | $duration = new Duration(125, TimeUnit::second());
38 | $this->assertEquals(2, $duration->toMinutes()->getValue());
39 | $duration = new Duration(11, TimeUnit::second());
40 | $this->assertEquals(0, $duration->toMinutes()->getValue());
41 |
42 | $duration = new Duration(13, TimeUnit::minute());
43 | $this->assertEquals($duration, $duration->toMinutes());
44 |
45 | $duration = new Duration(3, TimeUnit::hour());
46 | $this->assertEquals(180, $duration->toMinutes()->getValue());
47 |
48 | $duration = new Duration(4, TimeUnit::day());
49 | $this->assertEquals(5760, $duration->toMinutes()->getValue());
50 |
51 | $duration = new Duration(2, TimeUnit::week());
52 | $this->assertEquals(20160, $duration->toMinutes()->getValue());
53 |
54 | try {
55 | $duration = new Duration(2, TimeUnit::year());
56 | $duration->toMinutes();
57 | $this->assertEquals(true, false);
58 | } catch (\LogicException $e) {
59 | $this->assertEquals(true, true);
60 | }
61 | }
62 |
63 | public function testToHours()
64 | {
65 | $duration = new Duration(8200, TimeUnit::second());
66 | $this->assertEquals(2, $duration->toHours()->getValue());
67 | $duration = new Duration(100, TimeUnit::second());
68 | $this->assertEquals(0, $duration->toHours()->getValue());
69 |
70 | $duration = new Duration(60, TimeUnit::minute());
71 | $this->assertEquals(1, $duration->toHours()->getValue());
72 |
73 | $duration = new Duration(3, TimeUnit::hour());
74 | $this->assertEquals($duration, $duration->toHours());
75 |
76 | $duration = new Duration(0, TimeUnit::day());
77 | $this->assertEquals(0, $duration->toHours()->getValue());
78 | $duration = new Duration(4, TimeUnit::day());
79 | $this->assertEquals(96, $duration->toHours()->getValue());
80 |
81 | $duration = new Duration(1, TimeUnit::week());
82 | $this->assertEquals(168, $duration->toHours()->getValue());
83 |
84 | try {
85 | $duration = new Duration(2, TimeUnit::year());
86 | $duration->toMinutes();
87 | $this->assertEquals(true, false);
88 | } catch (\LogicException $e) {
89 | $this->assertEquals(true, true);
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/src/Ddd/Mail/Tests/Acceptance/TextMailTest.php:
--------------------------------------------------------------------------------
1 | mail = new TextMail(new Contact('rouffj@gmail.com'));
19 | }
20 |
21 | public function testWhenSuccessfullySentWithSwiftMailer()
22 | {
23 | $swiftMailer = $this->getMock('Swift_Mailer', array(), array(), '', false);
24 | $this->mail->compose('Subject', 'Here is the body');
25 | $this->mail->addRecipient(new Contact('foo@bar.com', 'Foo Bar'));
26 |
27 | $swiftMailer->expects($this->once())->method('send');
28 | $this->mail->send($mailer = new SwiftMailer($swiftMailer));
29 |
30 | $msg = $mailer->getSentMessage();
31 | $this->assertEquals('Subject', $msg->getSubject());
32 | $this->assertEquals('Here is the body', $msg->getBody());
33 | $this->assertEquals(array('foo@bar.com' => 'Foo Bar'), $msg->getTo());
34 | $this->assertEquals(array('rouffj@gmail.com' => null), $msg->getFrom());
35 | $this->assertEquals('text/plain', $msg->getContentType());
36 | $this->assertEquals('utf-8', $msg->getCharset());
37 | $this->assertEquals(array(), $this->mail->getFailedRecipients());
38 | }
39 |
40 | public function testWhenSuccessfullySentWithSesAmazon()
41 | {
42 | $amazonMailer = $this->getMock('Aws\Ses\SesClient', array(), array(), '', false);
43 | $command = $this->getMock('Guzzle\Service\Command\CommandInterface', array(), array(), '', false);
44 | $this->mail->compose('Subject', 'Here is the body');
45 | $this->mail->addRecipient(new Contact('foo@bar.com', 'Foo Bar'));
46 |
47 | $command->expects($this->once())->method('execute');
48 | $amazonMailer->expects($this->once())->method('getCommand')->will($this->returnValue($command));
49 | $this->mail->send($mailer = new AmazonSesMailer($amazonMailer));
50 |
51 | $msg = $mailer->getSentMessage();
52 | $this->assertEquals($this->mail->getSubject(), $msg['Message']['Subject']['Data']);
53 | $this->assertEquals($this->mail->getBody(), $msg['Message']['Body']['Text']['Data']);
54 | $this->assertEquals($this->mail->getFrom()->toString(), $msg['Source']);
55 | $this->assertEquals(array('foo@bar.com'), $msg['Destination']['ToAddresses']);
56 | $this->assertEquals('utf-8', $msg['Message']['Subject']['Charset']);
57 | $this->assertEquals('utf-8', $msg['Message']['Body']['Text']['Charset']);
58 | }
59 |
60 | public function testWhenFailedSentWithSwiftMailer()
61 | {
62 | $swiftMailer = $this->getMock('Swift_Mailer', array(), array(), '', false);
63 | $this->mail->compose('Subject', null);
64 | $this->mail->addRecipient(new Contact('foo@bar.com', 'Foo Bar'));
65 |
66 | $swiftMailer->expects($this->once())->method('send')->will($this->returnCallback(function($message, &$failedRecipients) {
67 | $failedRecipients = array('foo@bar.com');
68 | }));
69 | $this->mail->send($mailer = new SwiftMailer($swiftMailer));
70 |
71 | $msg = $mailer->getSentMessage();
72 | $this->assertEquals(array(new Contact('foo@bar.com')), $this->mail->getFailedRecipients());
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Ddd/Time/README.md:
--------------------------------------------------------------------------------
1 | TimeMachine
2 | ===========
3 |
4 | Installation
5 | ------------
6 |
7 | Using Composer, just require the `ddd/time` package:
8 |
9 | ``` javascript
10 | {
11 | "require": {
12 | "ddd/time": "dev-master"
13 | }
14 | }
15 | ```
16 |
17 | Howtos
18 | ------
19 |
20 | ```
21 | Ddd\Time\Tests\HowTo\DateInterval
22 | [x] How to get number of days between 2 dates
23 | [ ] How to get number of hours between 2 dates
24 | [ ] How to get number of minutes between 2 dates
25 | [ ] How to get number of seconds between 2 dates
26 | [x] How to get each day between 2 dates
27 | [x] How to know if a date interval is before after during other date interval
28 | [ ] How to know if a date interval is before after during a given date
29 | [x] How to know if a date interval is before after during a given time interval
30 | [ ] How to know if a date interval is before after during a given time point
31 | [ ] How to tranform date interval into time interval
32 |
33 | Ddd\Time\Tests\HowTo\Date
34 | [x] How to create a date only
35 | [x] How to come back at begin of current week
36 | [x] How to know if a date is after before equal to an other
37 | [x] How to convert a ddd time date object into regular date time object
38 | [x] How to know if date is during weekend or weekday
39 | [x] How to get previous next date
40 | [x] How to add remove a duration from it in days
41 | [ ] How to add remove a duration from it in years months weeks
42 | [ ] How to add remove a duration from it in hours minutes seconds
43 | [x] How to add remove a composite duration
44 | [x] How to transform a date into a time point
45 | [x] How to know diff between it and an other date
46 | [ ] How to know diff between it and a time point
47 | [x] How to know if date is before during after a date interval
48 |
49 | Ddd\Time\Tests\HowTo\Duration
50 | [x] How to know how long x days in hours minutes seconds
51 | [x] How to know how long x weeks in days hours minutes seconds
52 | [x] How to know how long x months in weeks days hours minutes seconds
53 | [x] How to know how long x years in months weeks days hours minutes seconds
54 | [ ] How to know how long a years b months c weeks d days in hours minutes seconds
55 |
56 | Ddd\Time\Tests\HowTo\TimeInterval
57 | [ ] How to know if a time interval is before after during an other time interval
58 | [ ] How to know if a time interval is before after during a given date interval
59 | [ ] How to know if a time interval is before after during a given date
60 | [ ] How to know if a time interval is before after during a given date time
61 | [ ] How to transform a time interval into a date interval destroy data
62 | [ ] How to know how long a time interval are in at least seconds minutes hours days weeks years
63 | [x] How to transform string representation of time interval into an object
64 |
65 | Ddd\Time\Tests\HowTo\TimeOfDay
66 | [x] How to know if a time of day is before after equal an other time of day
67 | [x] How to know if it is the ante meridian post meridian
68 |
69 | Ddd\Time\Tests\HowTo\TimePoint
70 | [x] How to know if it is before after equal an other time point
71 | [x] How to know if it is before after equal a given date
72 | [x] How to know if it is before after during a given date interval
73 | [x] How to know if it is before after equals a given time interval
74 | [x] How to know if it is during night or daylight
75 | [x] How to add remove duration from it
76 | [x] How to convert a ddd time point object into regular date timeobject
77 | [x] How to know if time point is before during after a time interval
78 | ```
79 |
80 | Credits
81 | -------
82 |
83 | - Joseph Rouff
84 | - Inspired by http://timeandmoney.sourceforge.net/timealgebra.html
85 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/Model/TimeIntervalTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($expectedDuration, $interval->getLength());
21 | }
22 |
23 | public function testIsBefore()
24 | {
25 | $interval = TimeIntervalFactory::create('2012-01-01 20:00', '2012-01-01 21:59');
26 | $intervalA = TimeIntervalFactory::create('2012-01-01 19:30', '2012-01-01 19:59'); // is before
27 | $intervalB = TimeIntervalFactory::create('2012-01-01 19:30', '2012-01-01 20:10'); // is not before
28 |
29 | $this->assertFalse($interval->isBefore($intervalA));
30 | $this->assertTrue($intervalA->isBefore($interval));
31 | $this->assertFalse($intervalB->isBefore($interval));
32 | $this->assertFalse($interval->isBefore($intervalB));
33 | //TimeIntervalFactory::create('2012-01-01 19:30', '2012-01-01 20:00'); // is before
34 | //TimeIntervalFactory::create('2012-01-01 22:00', '2012-01-01 22:30'); // is after
35 | //TimeIntervalFactory::create('2012-01-01 19:30', '2012-01-01 21:30'); // is during
36 | //TimeIntervalFactory::create('2012-01-01 21:30', '2012-01-01 22:30'); // is during
37 | //TimeIntervalFactory::create('2012-01-01 15:00', '2012-01-01 23:00'); // is during?
38 | }
39 |
40 | public function testIsAfter()
41 | {
42 | $interval = TimeIntervalFactory::create('2012-01-01 20:00', '2012-01-01 21:59');
43 | $intervalA = TimeIntervalFactory::create('2012-01-01 22:00', '2012-01-01 22:30'); // is after
44 |
45 | $this->assertFalse($interval->isAfter($intervalA));
46 | $this->assertTrue($intervalA->isAfter($interval));
47 | }
48 |
49 | public function testIsDuring()
50 | {
51 | $interval = TimeIntervalFactory::create('2012-01-01 20:00', '2012-01-01 21:59');
52 | $intervalA = TimeIntervalFactory::create('2012-01-01 19:30', '2012-01-01 21:30'); // is during
53 | $intervalB = TimeIntervalFactory::create('2012-01-01 21:30', '2012-01-01 22:30'); // is during
54 | $intervalC = TimeIntervalFactory::create('2012-01-01 15:00', '2012-01-01 23:00'); // is during?
55 |
56 | $this->assertTrue($interval->isDuring($intervalA));
57 | $this->assertTrue($intervalA->isDuring($interval));
58 |
59 | $this->assertTrue($interval->isDuring($intervalB));
60 | $this->assertTrue($intervalB->isDuring($interval));
61 |
62 | $this->assertTrue($interval->isDuring($intervalC));
63 | $this->assertTrue($intervalC->isDuring($interval));
64 | }
65 |
66 | public function testIsInclude()
67 | {
68 | $interval = TimeIntervalFactory::create('2013-01-13 01:00', '2013-01-14 18:30');
69 |
70 | $this->markTestIncomplete('Method should be implemented');
71 | $this->assertTrue($interval->isInclude(TimeIntervalFactory::create('2013-01-13 00:59', '2013-01-14 18:30')));
72 | $this->assertTrue($interval->isInclude($interval));
73 | $this->assertTrue($interval->isInclude(TimeIntervalFactory::create('2013-01-13 01:00', '2013-01-14 18:31')));
74 | $this->assertTrue($interval->isInclude(DateIntervalFactory::create('2013-01-13', '2013-01-14')));
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/DateInterval.php:
--------------------------------------------------------------------------------
1 | isBefore($begin)) {
14 | throw new \Exception('DateInterval: the begin date must be before the end date.');
15 | }
16 |
17 | $this->begin = $begin;
18 | $this->end = $end;
19 | $this->current = $this->begin;
20 | }
21 |
22 | public function nextDate()
23 | {
24 | $this->current = $this->current->next();
25 |
26 | return !$this->current->isAfter($this->end);
27 | }
28 |
29 | public function getCurrent()
30 | {
31 | return $this->current;
32 | }
33 |
34 | /**
35 | * Get duration in days separating the begin and end date of DateInterval.
36 | *
37 | * @return Duration Expressed in days.
38 | */
39 | public function getDuration()
40 | {
41 | return $this->begin->diff($this->end);
42 | }
43 |
44 | /**
45 | * Gets the begin value
46 | *
47 | * @return Date
48 | */
49 | public function getBegin()
50 | {
51 | return $this->begin;
52 | }
53 |
54 | /**
55 | * Gets the end value
56 | *
57 | * @return Date
58 | */
59 | public function getEnd()
60 | {
61 | return $this->end;
62 | }
63 |
64 | /**
65 | * @param IntervalInterface $other
66 | * @return bool
67 | */
68 | public function isBefore(IntervalInterface $other)
69 | {
70 | $begin = ($other instanceof TimeInterval) ? $other->getBegin()->getDate() : $other->getBegin();
71 | $end = ($other instanceof TimeInterval) ? $other->getEnd()->getDate() : $other->getEnd();
72 |
73 | return $this->begin->isBefore($begin) && $this->begin->isBefore($end);
74 | }
75 |
76 | /**
77 | * @param IntervalInterface $other
78 | * @return bool
79 | */
80 | public function isAfter(IntervalInterface $other)
81 | {
82 | $begin = ($other instanceof TimeInterval) ? $other->getBegin()->getDate() : $other->getBegin();
83 | $end = ($other instanceof TimeInterval) ? $other->getEnd()->getDate() : $other->getEnd();
84 |
85 | return $this->begin->isAfter($begin) && $this->begin->isAfter($end);
86 | }
87 |
88 | /**
89 | * @param IntervalInterface $other
90 | * @return bool
91 | */
92 | public function isDuring(IntervalInterface $other)
93 | {
94 | $begin = $this->begin->toDateTime();
95 | $end = $this->end->toDateTime();
96 |
97 | return
98 | $begin === max($begin, $other->getBegin()->toDateTime()) &&
99 | $end === min($end, $other->getEnd()->toDateTime())
100 | ;
101 | }
102 |
103 | public function isPartiallyBefore(IntervalInterface $interval)
104 | {
105 | throw new \Exception('Not implemented');
106 | }
107 |
108 | public function isPartiallyAfter(IntervalInterface $interval)
109 | {
110 | throw new \Exception('Not implemented');
111 | }
112 |
113 | public function isInclude(IntervalInterface $other)
114 | {
115 | $otherBegin = ($other instanceof TimeInterval) ? $other->getBegin()->getDate() : $other->getBegin();
116 | $otherEnd = ($other instanceof TimeInterval) ? $other->getEnd()->getDate() : $other->getEnd();
117 |
118 | return
119 | ($this->begin->isBefore($otherBegin) || $this->begin->isEquals($otherBegin)) &&
120 | ($this->end->isAfter($otherEnd) || $this->end->isEquals($otherEnd))
121 | ;
122 | }
123 | }
124 |
125 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/HowTo/DateIntervalTest.php:
--------------------------------------------------------------------------------
1 | getDuration();
18 |
19 | $this->assertEquals(new Duration(19, TimeUnit::day()), $duration);
20 | }
21 |
22 | public function testHowToGetNumberOfHoursBetween2Dates()
23 | {
24 | $interval = new DateInterval(new Date(2013, 1, 1), new Date(2013, 1, 3));
25 | $duration = $interval->getDuration();
26 |
27 | $this->assertEquals(new Duration(48, TimeUnit::hour()), $duration->toHours()); // 2 days
28 | }
29 |
30 | public function testHowToGetNumberOfMinutesBetween2Dates()
31 | {
32 | $interval = new DateInterval(new Date(2013, 1, 1), new Date(2013, 1, 3));
33 | $duration = $interval->getDuration();
34 |
35 | $this->assertEquals(new Duration(60*24*2, TimeUnit::minute()), $duration->toMinutes()); // 2 days
36 | }
37 |
38 | public function testHowToGetNumberOfSecondsBetween2Dates()
39 | {
40 | $interval = new DateInterval(new Date(2013, 1, 1), new Date(2013, 1, 2));
41 | $duration = $interval->getDuration();
42 |
43 | $this->assertEquals(new Duration(60*60*24, TimeUnit::second()), $duration->toSeconds()); // 1 day
44 | }
45 |
46 | public function testHowToGetEachDayBetween2Dates()
47 | {
48 | $interval = new DateInterval(new Date(2013, 1, 1), new Date(2013, 1, 2));
49 | $duration = $interval->getDuration();
50 | $dates = array();
51 | do {
52 | $nextDate = $interval->getCurrent();
53 | $dates[] = $nextDate;
54 | } while ($interval->nextDate());
55 |
56 | $this->assertEquals(array(new Date(2013, 1, 1), new Date(2013, 1, 2)), $dates);
57 | }
58 |
59 | public function testHowToKnowIfADateIntervalIsBeforeAfterDuringOtherDateInterval()
60 | {
61 | $interval = new DateInterval(new Date(2013, 6, 1), new Date(2013, 6, 15));
62 | $before = new DateInterval(new Date(2013, 5, 20), new Date(2013, 5, 30));
63 | $after = new DateInterval(new Date(2013, 6, 16), new Date(2013, 6, 20));
64 | $during = new DateInterval(new Date(2013, 5, 1), new Date(2013, 6, 30));
65 | $partiallyDuring = new DateInterval(new Date(2013, 1, 1), new Date(2013, 6, 10));
66 |
67 | $this->assertTrue($interval->isBefore($after));
68 | $this->assertTrue($interval->isAfter($before));
69 | $this->assertTrue($interval->isDuring($during));
70 | $this->assertFalse($interval->isDuring($partiallyDuring));
71 | }
72 |
73 | public function testHowToKnowIfADateIntervalIsBeforeAfterDuringAGivenDate()
74 | {
75 | $this->markTestIncomplete();
76 | }
77 |
78 | public function testHowToKnowIfADateIntervalIsBeforeAfterDuringAGivenTimeInterval()
79 | {
80 | $jan10to20 = new DateInterval(new Date(2013, 1, 10), new Date(2013, 1, 20));
81 | $timeInterval = TimeIntervalFactory::create('2013-01-01 10:00', '2013-01-21 20:00');
82 |
83 | $this->assertFalse($jan10to20->isBefore($timeInterval));
84 | $this->assertTrue($jan10to20->isDuring($timeInterval));
85 | $this->assertFalse($jan10to20->isAfter($timeInterval));
86 | }
87 |
88 | public function testHowToKnowIfADateIntervalIsBeforeAfterDuringAGivenTimePoint()
89 | {
90 | $this->markTestIncomplete();
91 | }
92 |
93 | public function testHowToTranformDateIntervalIntoTimeInterval()
94 | {
95 | $this->markTestIncomplete();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/Date.php:
--------------------------------------------------------------------------------
1 | day = (int) $day;
17 | $this->month = (int) $month;
18 | $this->year = (int) $year;
19 | }
20 |
21 | public function during(Duration $duration)
22 | {
23 | $begin = new TimePoint($this->year, $this->month, $this->day, 0, 0);
24 | $end = $begin->plus($duration);
25 |
26 | return new DateInterval($begin->getDate(), $end->getDate());
27 | }
28 |
29 | public function minus(Duration $duration)
30 | {
31 | return $this->toTimePoint()->minus($duration)->getDate();
32 | }
33 |
34 | public function plus(Duration $duration)
35 | {
36 | return $this->toTimePoint()->plus($duration)->getDate();
37 | }
38 |
39 | public function isAfter(Date $date)
40 | {
41 | return
42 | $this->year > $date->getYear() ||
43 | ($this->year >= $date->getYear() && $this->month > $date->getMonth()) ||
44 | ($this->year >= $date->getYear() && $this->month >= $date->getMonth() && $this->day > $date->getDay())
45 | ;
46 | }
47 |
48 | public function diff(Date $date)
49 | {
50 | return new Duration($this->toDateTime()->diff($date->toDateTime())->d, TimeUnit::day());
51 | }
52 |
53 | public function isBefore(Date $date)
54 | {
55 | return
56 | false === $this->isAfter($date) &&
57 | false === $this->isEquals($date)
58 | ;
59 | }
60 |
61 | public function isEquals(Date $date)
62 | {
63 | return
64 | $this->year === $date->getYear() &&
65 | $this->month === $date->getMonth() &&
66 | $this->day === $date->getDay()
67 | ;
68 | }
69 |
70 | public function beginOfWeek()
71 | {
72 | $i = 0;
73 | $curDate = $this;
74 | while ($i < 8) {
75 | $dtime = $curDate->toDateTime();
76 | $numOfWeek = (int) $dtime->format('N');
77 | if (1 === $numOfWeek) {
78 | return $curDate;
79 | }
80 | $curDate = $curDate->previous();
81 | $i = $i + 1;
82 | }
83 | throw new \RunTimeException('Loop error with begin of week');
84 | }
85 |
86 | public function next()
87 | {
88 | return $this->plus(new Duration(1, TimeUnit::day()));
89 | }
90 |
91 | public function previous()
92 | {
93 | return $this->minus(new Duration(1, TimeUnit::day()));
94 | }
95 |
96 | public function toDateTime()
97 | {
98 | $dateTime = new \Datetime();
99 | $dateTime->setDate($this->year, $this->month, $this->day);
100 | $dateTime->setTime(0, 0, 0);
101 |
102 | return $dateTime;
103 | }
104 |
105 | public function toTimePoint()
106 | {
107 | return new TimePoint($this->year, $this->month, $this->day, null, null);
108 | }
109 |
110 | public function toDateInterval()
111 | {
112 | return new DateInterval($this, $this);
113 | }
114 |
115 | public function isWeekDay()
116 | {
117 | return !$this->isWeekEndDay();
118 | }
119 |
120 | public function isWeekEndDay()
121 | {
122 | return intval($this->toDateTime()->format('w')) === self::SUNDAY || intval($this->toDateTime()->format('w')) === self::SATURDAY;
123 | }
124 |
125 | /**
126 | * Gets the value of year
127 | *
128 | * @return int
129 | */
130 | public function getYear()
131 | {
132 | return $this->year;
133 | }
134 |
135 | /**
136 | * Gets the value of month
137 | *
138 | * @return int
139 | */
140 | public function getMonth()
141 | {
142 | return $this->month;
143 | }
144 |
145 | /**
146 | * Gets the value of day
147 | *
148 | * @return int
149 | */
150 | public function getDay()
151 | {
152 | return $this->day;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/HowTo/TimePointTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($second->isAfter($first), true);
24 | $this->assertEquals($second->isBefore($third), false);
25 | $this->assertEquals($first->isAfter($second), false);
26 | $this->assertEquals($third->isEquals($second), true);
27 | }
28 |
29 | public function testHowToKnowIfItIsBeforeAfterEqualAGivenDate()
30 | {
31 | $timePoint = new TimePoint(2013, 3, 12, 18, 27);
32 | $dateBefore = new Date(2013, 1, 1);
33 | $dateAfter = new Date(2013, 8, 15);
34 | $dateEqual = new Date(2013, 3, 12);
35 | $this->assertEquals(true, $dateBefore->isBefore($timePoint->getDate()));
36 | $this->assertEquals(true, $dateAfter->isAfter($timePoint->getDate()));
37 | $this->assertEquals(true, $dateEqual->isEquals($timePoint->getDate()));
38 | }
39 |
40 | public function testHowToKnowIfItIsBeforeAfterDuringAGivenDateInterval()
41 | {
42 | $timePoint = new TimePoint(2013, 3, 1, 18, 27);
43 | $dateInterval = new DateInterval(new Date(2013, 1, 1), new Date(2013, 1, 15));
44 |
45 | $this->assertEquals(true, $dateInterval->isBefore($timePoint->getDate()->toDateInterval()));
46 | $this->assertEquals(false, $dateInterval->isAfter($timePoint->getDate()->toDateInterval()));
47 | $this->assertEquals(false, $dateInterval->isDuring($timePoint->getDate()->toDateInterval()));
48 | }
49 |
50 | public function testHowToKnowIfItIsBeforeAfterEqualsAGivenTimeInterval()
51 | {
52 | $timePoint = new TimePoint(2013, 3, 1, 18, 27);
53 | $timeInterval = new TimeInterval(new TimePoint(2013, 1, 1, 0, 30), new TimePoint(2013, 1, 15, 23, 30));
54 |
55 | $this->assertEquals(true, $timeInterval->isBefore($timePoint->toTimeInterval()));
56 | $this->assertEquals(false, $timeInterval->isAfter($timePoint->toTimeInterval()));
57 | $this->assertEquals(false, $timeInterval->isDuring($timePoint->toTimeInterval()));
58 | }
59 |
60 | public function testHowToKnowIfItIsDuringNightOrDaylight()
61 | {
62 | $nightTimePoint = new TimePoint(2013, 3, 12, 3, 30);
63 | $dayTimePoint = new TimePoint(2013, 3, 12, 15, 30);
64 |
65 | // Using the Eiffel Tower's coordinates
66 | $this->assertTrue($nightTimePoint->isNightTime(48.8582, 2.2945));
67 | $this->assertFalse($dayTimePoint->isNightTime(48.8582, 2.2945));
68 | }
69 |
70 | public function testHowToAddRemoveDurationFromIt()
71 | {
72 | $startTimePoint = new TimePoint(2013, 3, 12, 18, 27);
73 | $stopTimePoint = new TimePoint(2013, 3, 14, 18, 27);
74 | $duration = new Duration(2, TimeUnit::day());
75 | $result = $startTimePoint->plus($duration);
76 | $this->assertEquals($result, $stopTimePoint);
77 | }
78 |
79 | public function testHowToConvertADddTimePointObjectIntoRegularDateTimeobject()
80 | {
81 | $timepoint = new TimePoint(2013, 3, 12, 18, 27, 11);
82 | $datetime = new \DateTime();
83 | $datetime->setDate(2013, 3, 12);
84 | $datetime->setTime(18, 27, 11);
85 | $this->assertEquals($timepoint->toDateTime(), $datetime);
86 | }
87 |
88 | public function testHowToKnowIfTimePointIsBeforeDuringAfterATimeInterval()
89 | {
90 | $doctorAppointment = new TimePoint(2013, 1, 5, 10, 0);
91 | $doctorAppointment = $doctorAppointment->toTimeInterval();
92 | $samBrithdayParty = TimeIntervalFactory::create('2013-01-05 11:30', '2013-01-05 13:00');
93 | $sportSession = TimeIntervalFactory::create('2013-01-05 09:00', '2013-01-05 10:30');
94 |
95 | $this->assertTrue($doctorAppointment->isBefore($samBrithdayParty));
96 | $this->assertTrue($doctorAppointment->isDuring($sportSession));
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/TimePoint.php:
--------------------------------------------------------------------------------
1 | date = new Date($year, $month, $day);
15 | $this->time = new TimeOfDay($hour, $minute, $second);
16 | }
17 |
18 | public function during(Duration $duration)
19 | {
20 | $interval = $this->plus($duration);
21 |
22 | return new TimeInterval($this, $interval);
23 | }
24 |
25 | public function until(TimePoint $point)
26 | {
27 | return new TimeInterval($this, $point);
28 | }
29 |
30 | public function plus(Duration $duration)
31 | {
32 | $date = $this->toDateTime();
33 | $date->add($duration->asPHPDateInterval());
34 |
35 | return TimePointFactory::fromDateTime($date);
36 | }
37 |
38 | public function minus(Duration $duration)
39 | {
40 | $date = $this->toDateTime();
41 | $date->sub($duration->asPHPDateInterval());
42 |
43 | return TimePointFactory::fromDateTime($date);
44 | }
45 |
46 | public function isAfter(TimePoint $point)
47 | {
48 | if ($this->date->isEquals($point->getDate())) {
49 | if ($this->time->isAfter($point->getTimeOfDay())){
50 | return true;
51 | }
52 | } else if ($this->date->isAfter($point->getDate())) {
53 | return true;
54 | }
55 |
56 | return false;
57 | }
58 |
59 | public function isBefore(TimePoint $other)
60 | {
61 | return
62 | !$this->isAfter($other) &&
63 | !$this->isEquals($other);
64 | }
65 |
66 | public function isEquals(TimePoint $point)
67 | {
68 | return
69 | $this->date->isEquals($point->getDate()) &&
70 | $this->time->isEquals($point->getTimeOfDay())
71 | ;
72 | }
73 |
74 | /**
75 | * Gets the value of year
76 | *
77 | * @return int
78 | */
79 | public function getYear()
80 | {
81 | return $this->date->getYear();
82 | }
83 |
84 | /**
85 | * Gets the value of month
86 | *
87 | * @return int
88 | */
89 | public function getMonth()
90 | {
91 | return $this->date->getMonth();
92 | }
93 |
94 | /**
95 | * Gets the value of day
96 | *
97 | * @return int
98 | */
99 | public function getDay()
100 | {
101 | return $this->date->getDay();;
102 | }
103 |
104 | public function getHour()
105 | {
106 | return $this->time->getHour();
107 | }
108 |
109 | public function getMinutes()
110 | {
111 | return $this->time->getMinutes();
112 | }
113 |
114 | public function getSeconds()
115 | {
116 | return $this->time->getSeconds();
117 | }
118 |
119 | public function toDateTime()
120 | {
121 | $dtime = $this->date->toDateTime();
122 | $dtime->setTime($this->time->getHour(), $this->time->getMinutes(), $this->time->getSeconds());
123 |
124 | return $dtime;
125 | }
126 |
127 | public function toTimeInterval()
128 | {
129 | return new TimeInterval($this, $this);
130 | }
131 |
132 | public function getDate()
133 | {
134 | return $this->date;
135 | }
136 |
137 | public function getTimeOfDay()
138 | {
139 | return $this->time;
140 | }
141 |
142 | public function isNightTime($latitude, $longitude)
143 | {
144 | $yesterdaySunset = date_sunset($this->date->previous()->toDateTime()->getTimestamp(), SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude);
145 | $todaySunrise = date_sunrise($this->date->toDateTime()->getTimestamp(), SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude);
146 |
147 | if (false === $yesterdaySunset || false === $todaySunrise) {
148 | throw new \RuntimeException('PHP could not determine the sun information.');
149 | }
150 |
151 | return ($this->isAfter(TimePointFactory::fromTimestamp($yesterdaySunset))
152 | && $this->isBefore(TimePointFactory::fromTimestamp($todaySunrise)));
153 | }
154 |
155 | public function __toString()
156 | {
157 | return strtr('{year}/{month}/{day} at {time}', array(
158 | '{year}' => $this->date->getYear(),
159 | '{month}' => $this->date->getMonth(),
160 | '{day}' => $this->date->getDay(),
161 | '{time}' => $this->time,
162 | ));
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Tests/HowTo/DateTest.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf('Ddd\Time\Model\Date', $date);
19 | }
20 |
21 | public function testHowToComeBackAtBeginOfCurrentWeek()
22 | {
23 | $friday = new Date(2013, 1, 4);
24 | $monday = $friday->beginOfWeek();
25 |
26 | $this->assertEquals(new Date(2012, 12, 31), $monday);
27 | }
28 |
29 | public function testHowToKnowIfADateIsAfterBeforeEqualToAnOther()
30 | {
31 | $jan1 = new Date(2013, 1, 1);
32 |
33 | $this->assertTrue($jan1->isBefore(new Date(2013, 1, 2)));
34 | $this->assertTrue($jan1->isAfter(new Date(2012, 12, 31)));
35 | $this->assertTrue($jan1->isEquals($jan1));
36 | }
37 |
38 | /**
39 | * Usecases:
40 | * - I want to display a date in custom format in templates.
41 | *
42 | */
43 | public function testHowToConvertADddTimeDateObjectIntoRegularDateTimeObject()
44 | {
45 | $jan1 = new Date(2013, 1, 1);
46 |
47 | $this->assertEquals(new \DateTime('2013-01-01 00:00:00'), $jan1->toDateTime());
48 | }
49 |
50 | public function testHowToKnowIfDateIsDuringWeekendOrWeekday()
51 | {
52 | $tuesday = new Date(2013, 1, 1);
53 | $saturday = $tuesday->plus(new Duration(4, TimeUnit::day()));
54 |
55 | $this->assertFalse($tuesday->isWeekEndDay());
56 | $this->assertTrue($tuesday->isWeekDay());
57 | $this->assertTrue($saturday->isWeekEndDay());
58 | $this->assertFalse($saturday->isWeekDay());
59 | }
60 |
61 | public function testHowToGetPreviousNextDate()
62 | {
63 | $jan1 = new Date(2013, 1, 1);
64 | $dec31 = $jan1->previous();
65 | $jan2 = $jan1->next();
66 |
67 | $this->assertEquals(new Date(2012, 12, 31), $dec31);
68 | $this->assertEquals(new Date(2013, 1, 2), $jan2);
69 | }
70 |
71 | public function testHowToAddRemoveADurationFromItInDays()
72 | {
73 | $jan1 = new Date(2013, 1, 1);
74 | $dec31 = $jan1->minus(new Duration(1, TimeUnit::day()));
75 | $jan3 = $jan1->plus(new Duration(2, TimeUnit::day()));
76 |
77 | $this->assertEquals(new Date(2012, 12, 31), $dec31);
78 | $this->assertEquals(new Date(2013, 1, 3), $jan3);
79 | }
80 |
81 | public function testHowToAddRemoveADurationFromItInYearsMonthsWeeks()
82 | {
83 | $this->markTestIncomplete();
84 | }
85 |
86 | public function testHowToAddRemoveADurationFromItInHoursMinutesSeconds()
87 | {
88 | $this->markTestIncomplete();
89 | }
90 |
91 | /**
92 | * eg. Allow to add/remove 2 days, 5 hours and 42 minutes easily.
93 | */
94 | public function testHowToAddRemoveACompositeDuration()
95 | {
96 | }
97 |
98 | public function testHowToTransformADateIntoATimePoint()
99 | {
100 | $jan1 = new Date(2013, 1, 1);
101 | $timePoint = $jan1->toTimePoint();
102 |
103 | $this->assertInstanceOf('Ddd\Time\Model\TimePoint', $timePoint);
104 | $this->assertEquals($timePoint->getYear(), 2013);
105 | $this->assertEquals($timePoint->getMonth(), 1);
106 | $this->assertEquals($timePoint->getDay(), 1);
107 | $this->assertEquals($timePoint->getHour(), 0);
108 | $this->assertEquals($timePoint->getMinutes(), 0);
109 | $this->assertEquals($timePoint->getSeconds(), 0);
110 | }
111 |
112 | /**
113 | * Use cases :
114 | * - Calculate difference between 2 days
115 | * - Fetch the position of a date from another
116 | * - How many days form my birthday
117 | *
118 | * Returns a Duration Class @see Ddd\Time\Model\Duration.
119 | *
120 | */
121 | public function testHowToKnowDiffBetweenItAndAnOtherDate()
122 | {
123 | $jan1 = new Date(2013, 1, 1);
124 | $jan10 = new Date(2013, 1, 10);
125 | $diff = $jan1->diff($jan10);
126 |
127 | $this->assertInstanceOf('Ddd\Time\Model\Duration', $diff);
128 | $this->assertEquals($diff, new Duration(9, TimeUnit::day()));
129 | }
130 |
131 | public function testHowToKnowDiffBetweenItAndATimePoint()
132 | {
133 | $this->markTestIncomplete('Should return a composite duration');
134 | }
135 |
136 | public function testHowToKnowIfDateIsBeforeDuringAfterADateInterval()
137 | {
138 | $winterHolidays2013 = DateIntervalFactory::create('2012-12-20', '2013-01-05');
139 | $dadVisit = new Date(2012, 12, 29);
140 | $dadVisit = $dadVisit->toDateInterval();
141 |
142 | $this->assertTrue($dadVisit->isDuring($winterHolidays2013));
143 | $this->assertFalse($dadVisit->isBefore($winterHolidays2013));
144 | $this->assertFalse($dadVisit->isAfter($winterHolidays2013));
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Tests/Model/CalendarTest.php:
--------------------------------------------------------------------------------
1 | calendar = new Calendar('foo calendar', array(
27 | new Event(TimeIntervalFactory::create('2012-01-15 16:00', '2012-01-15 18:30')),
28 | new Event(TimeIntervalFactory::create('2012-01-20 08:00', '2012-01-23 08:00')),
29 | ));
30 | }
31 |
32 | public function testConstructor()
33 | {
34 | $this->assertCount(2, $this->calendar);
35 | foreach ($this->calendar as $event) {
36 | $this->assertTrue($event instanceof EventInterface);
37 | }
38 | }
39 |
40 | public function testDefaultCursor()
41 | {
42 | $cursor = new TimePoint(2012, 1, 15, 16, 0);
43 | $this->assertEquals($cursor, $this->calendar->getCursor());
44 | }
45 |
46 | public function testCursorFiltering()
47 | {
48 | $this->calendar->setCursor(new TimePoint(2012, 1, 15, 15, 59));
49 | $this->assertSame(2, $this->calendar->countRemaining());
50 |
51 | $this->calendar->setCursor(new TimePoint(2012, 1, 17, 0, 0));
52 | $this->assertSame(1, $this->calendar->countRemaining());
53 |
54 | $this->calendar->setCursor(new TimePoint(2012, 1, 23, 8, 1));
55 | $this->assertSame(0, $this->calendar->countRemaining());
56 | }
57 |
58 | public function testBetween()
59 | {
60 | $this->assertCount(0, $this->calendar->between(new TimeInterval(new TimePoint(2012, 1, 1, 0, 0), new TimePoint(2012, 1, 15, 15, 59, 59))));
61 | $this->assertCount(1, $this->calendar->between(new TimeInterval(new TimePoint(2012, 1, 1, 0, 0), new TimePoint(2012, 1, 15, 16, 1, 0))));
62 |
63 | $this->assertCount(0, $this->calendar->between(new TimeInterval(new TimePoint(2012, 1, 23, 8, 1, 0), new TimePoint(2012, 2, 0, 0, 0))));
64 | $this->assertCount(1, $this->calendar->between(new TimeInterval(new TimePoint(2012, 1, 20, 7, 59, 59), new TimePoint(2012, 2, 0, 0, 0))));
65 |
66 | $this->assertCount(0, $this->calendar->between(new TimeInterval(new TimePoint(2012, 1, 15, 18, 31, 0), new TimePoint(2012, 1, 20, 7, 59, 59))));
67 | $this->assertCount(2, $this->calendar->between(new TimeInterval(new TimePoint(2012, 1, 15, 18, 29, 59), new TimePoint(2012, 1, 20, 8, 0, 1))));
68 | }
69 |
70 | public function testAdd()
71 | {
72 | $this->assertCount(2, $this->calendar);
73 |
74 | $this->calendar->add(new Event(TimeIntervalFactory::create('2012-01-01 20:00', '2012-01-01 21:59')));
75 | $this->assertCount(3, $this->calendar);
76 |
77 | // AllowOverlapStrategy
78 | $this->calendar->add(new Event(TimeIntervalFactory::create('2012-01-01 19:30', '2012-01-01 19:59')));
79 | $this->assertCount(4, $this->calendar);
80 | $this->assertCount(2, $this->calendar->between(TimeIntervalFactory::create('2012-01-01 19:30', '2012-01-01 21:30')));
81 | }
82 |
83 | public function testUpdate()
84 | {
85 | $originalEvent = current(iterator_to_array($this->calendar));
86 | $updatedEvent = new Event(TimeIntervalFactory::create('2012-01-15 17:00', '2012-01-15 19:30'));
87 | $this->calendar->update($originalEvent, $updatedEvent);
88 |
89 | $this->assertCount(2, $this->calendar);
90 | $this->assertSame($updatedEvent, current(iterator_to_array($this->calendar)));
91 | }
92 |
93 | public function testGroup()
94 | {
95 | $cal = new Calendar('my calendar');
96 | $cal->add(new Event(TimeIntervalFactory::create('2012-01-01 01:00', '2012-01-01 10:00')));
97 | $cal->add(new Event(TimeIntervalFactory::create('2012-01-03 01:01', '2012-01-03 10:00')));
98 |
99 | $cal->group(new Duration(1, TimeUnit::day()));
100 | $this->assertCount(3, $cal->getCalendars());
101 | }
102 |
103 | public function testAddWithNoOverlapStrategy()
104 | {
105 | $this->calendar->setStrategy(new NoOverlapStrategy());
106 | $this->assertCount(2, $this->calendar);
107 |
108 | $this->calendar->add(new Event(TimeIntervalFactory::create('2012-01-15 15:30', '2012-01-15 15:59')));
109 | $this->assertCount(3, $this->calendar);
110 |
111 | try {
112 | $this->calendar->add(new Event(TimeIntervalFactory::create('2012-01-15 15:00', '2012-01-15 15:40')));
113 | $this->fail('A CalendarEventException should be thrown');
114 | } catch (CalendarEventException $e) {
115 | }
116 |
117 | try {
118 | // exact same Event as reference
119 | $this->calendar->add(new Event(TimeIntervalFactory::create('2012-01-15 15:30', '2012-01-15 15:59')));
120 | $this->fail('A CalendarEventException should be thrown');
121 | } catch (CalendarEventException $e) {
122 | }
123 |
124 | $this->calendar->add(new Event(TimeIntervalFactory::create('2012-01-16 17:50', '2012-01-17 18:00')));
125 | $this->assertCount(4, $this->calendar);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/Ddd/Calendar/Model/Calendar.php:
--------------------------------------------------------------------------------
1 |
19 | */
20 | class Calendar implements CalendarInterface
21 | {
22 | /**
23 | * @var EventInterface[]
24 | */
25 | private $events;
26 |
27 | /**
28 | * @var Event[]
29 | */
30 | private $calendars;
31 |
32 | /**
33 | * @var StrategyInterface
34 | */
35 | private $strategy;
36 |
37 | /**
38 | * @var string
39 | */
40 | private $title;
41 |
42 | /**
43 | * @var TimePoint
44 | */
45 | private $cursor;
46 |
47 | /**
48 | * @param string $title
49 | * @param array $events
50 | * @param StrategyInterface|null $strategy
51 | */
52 | public function __construct($title, array $events = array(), StrategyInterface $strategy = null)
53 | {
54 | $this->strategy = (null === $strategy) ? new BaseStrategy() : $strategy;
55 | $this->title = $title;
56 | $this->events = array();
57 | $this->calendars = array();
58 |
59 | foreach ($events as $event) {
60 | $this->add($event);
61 | }
62 | $this->cursor = (0 === count($this->events)) ? TimePointFactory::now() : $this->events[0]->getInterval()->getBegin();
63 | //$this->cursor = null;
64 | }
65 |
66 | /**
67 | * {@inheritdoc}
68 | */
69 | public function between(TimeInterval $interval, $title = '')
70 | {
71 | $selectedEvents = $this->getEvents($interval->getBegin(), $interval->getEnd());
72 | $narrowerCalendar = new self($title, $selectedEvents, $this->strategy);
73 |
74 | return $narrowerCalendar;
75 | }
76 |
77 | /**
78 | * {@inheritdoc}
79 | */
80 | public function getEventAfter(TimePoint $point)
81 | {
82 | foreach ($this->events as $event) {
83 | if ($event->getInterval()->getBegin()->isAfter($point)) {
84 | return $event;
85 | }
86 | }
87 | }
88 |
89 | /**
90 | * {@inheritdoc}
91 | */
92 | public function add(EventInterface $newEvent)
93 | {
94 | $this->events = $this->strategy->add($newEvent, $this->events);
95 | $this->checkCursor();
96 | }
97 |
98 | /**
99 | * {@inheritdoc}
100 | */
101 | public function remove(EventInterface $event)
102 | {
103 | $this->events = $this->strategy->remove($event, $this->events);
104 | $this->checkCursor();
105 | }
106 |
107 | /**
108 | * {@inheritdoc}
109 | */
110 | public function update(EventInterface $originalEvent, EventInterface $updatedEvent)
111 | {
112 | $this->events = $this->strategy->update($originalEvent, $updatedEvent, $this->events);
113 | $this->checkCursor();
114 | }
115 |
116 | /**
117 | * {@inheritdoc}
118 | */
119 | public function setCursor(TimePoint $cursor)
120 | {
121 | $this->cursor = $cursor;
122 | }
123 |
124 | /**
125 | * {@inheritdoc}
126 | */
127 | public function getCursor()
128 | {
129 | return $this->cursor;
130 | }
131 |
132 | /**
133 | * @return string
134 | */
135 | public function setTitle($title)
136 | {
137 | $this->title = $title;
138 | }
139 |
140 | public function getFirst()
141 | {
142 | return reset($this->events);
143 | }
144 |
145 | public function getLast()
146 | {
147 | return end($this->events);
148 | }
149 |
150 | public function group(Duration $duration)
151 | {
152 | $calendars = array();
153 | $first = $current = $this->getFirst()->getInterval()->getBegin();
154 | $end = $this->getLast()->getInterval()->getEnd();
155 | while (!$current->isAfter($end)) {
156 | $newCurrent = $current->plus($duration);
157 | $this->calendars[] = $this->between($current->until($newCurrent));
158 | $current = $newCurrent;
159 | }
160 | }
161 |
162 | public function getCalendars()
163 | {
164 | return $this->calendars;
165 | }
166 |
167 | /**
168 | * {@inheritdoc}
169 | */
170 | public function getTitle()
171 | {
172 | return $this->title;
173 | }
174 |
175 | /**
176 | * @param StrategyInterface $strategy
177 | */
178 | public function setStrategy($strategy)
179 | {
180 | $this->strategy = $strategy;
181 | }
182 |
183 | /**
184 | * @return StrategyInterface
185 | */
186 | public function getStrategy()
187 | {
188 | return $this->strategy;
189 | }
190 |
191 | /**
192 | * {@inheritdoc}
193 | */
194 | public function getIterator()
195 | {
196 | return new \ArrayIterator($this->getEvents($this->cursor));
197 | }
198 |
199 | /**
200 | * {@inheritdoc}
201 | */
202 | public function count()
203 | {
204 | return count($this->events);
205 | }
206 |
207 | /**
208 | * {@inheritdoc}
209 | */
210 | public function countRemaining()
211 | {
212 | return count($this->getEvents($this->cursor));
213 | }
214 |
215 | /**
216 | * @param TimePoint $begin
217 | * @param null|TimePoint $end
218 | *
219 | * @return array
220 | */
221 | private function getEvents(TimePoint $begin, TimePoint $end = null)
222 | {
223 | $events = $this->events;
224 |
225 | $offset = 0;
226 | foreach ($events as $event) {
227 | if ($event->getInterval()->getEnd()->isAfter($begin) || $event->getInterval()->getEnd()->isEquals($begin)) {
228 | break;
229 | } else {
230 | $offset ++;
231 | }
232 | }
233 | $events = array_slice($events, $offset);
234 |
235 | if (null === $end) {
236 | return $events;
237 | }
238 |
239 | $length = count($events);
240 | foreach (array_reverse($events) as $event) {
241 | if ($end->isAfter($event->getInterval()->getBegin())) {
242 | break;
243 | } else {
244 | $length --;
245 | }
246 | }
247 |
248 | return array_slice($events, 0, $length);
249 | }
250 |
251 | public function offsetExists($offset)
252 | {
253 | return isset($this->events[$offset]);
254 | }
255 |
256 | public function offsetGet($offset)
257 | {
258 | return $this->offsetExists($offset) ? $this->events[$offset] : null;
259 | }
260 |
261 | public function offsetUnset($offset)
262 | {
263 | throw new BadMethodCallException('READ ONLY');
264 | }
265 |
266 | public function offsetSet($offset, $value)
267 | {
268 | throw new BadMethodCallException('READ ONLY');
269 | }
270 |
271 | private function checkCursor()
272 | {
273 | // @todo: implement this :)
274 | }
275 | }
276 |
--------------------------------------------------------------------------------
/src/Ddd/Time/Model/Duration.php:
--------------------------------------------------------------------------------
1 | value = $duration;
26 | $this->unit = $unit;
27 |
28 | if (TimeUnit::MONTH === $unit->getUnit() && (null === $year || null === $month)) {
29 | throw new \InvalidArgumentException(sprintf('Year and month should be provided to determine the duration.'));
30 | }
31 |
32 | if (TimeUnit::YEAR === $unit->getUnit() && null === $year) {
33 | throw new \InvalidArgumentException(sprintf('Year should be provided to determine the duration.'));
34 | }
35 |
36 | $this->year = $year;
37 | $this->month = $month;
38 | }
39 |
40 | public function asPHPDateInterval()
41 | {
42 | $timeSpec = ($this->unit->isTime()) ? 'PT' : 'P';
43 | $timeSpec = sprintf('%s%s%s', $timeSpec, $this->value, $this->unit->getCode());
44 |
45 | return new \DateInterval($timeSpec);
46 | }
47 |
48 | public function getValue()
49 | {
50 | return $this->value;
51 | }
52 |
53 | public function toSeconds()
54 | {
55 | if ($this->unit->getUnit() == TimeUnit::SECOND) {
56 | return $this;
57 | }
58 |
59 | if ($this->unit->getUnit() == TimeUnit::MINUTE) {
60 | return new Duration(self::NB_SECOND_PER_MINUTE * $this->value, TimeUnit::second());
61 | }
62 |
63 | if ($this->unit->getUnit() == TimeUnit::HOUR) {
64 | return new Duration(self::NB_SECOND_PER_HOUR * $this->value, TimeUnit::second());
65 | }
66 |
67 | if ($this->unit->getUnit() == TimeUnit::DAY) {
68 | return new Duration(self::NB_SECOND_PER_DAY * $this->value, TimeUnit::second());
69 | }
70 |
71 | if ($this->unit->getUnit() == TimeUnit::WEEK) {
72 | return new Duration(self::NB_SECOND_PER_WEEK, TimeUnit::second());
73 | }
74 |
75 | if (TimeUnit::MONTH === $this->unit->getUnit() || TimeUnit::YEAR === $this->unit->getUnit()) {
76 | return $this->toDays()->toSeconds();
77 | }
78 |
79 | throw new \LogicException('Can\'t convert duration.');
80 | }
81 |
82 | public function toMinutes()
83 | {
84 | if ($this->unit->getUnit() == TimeUnit::MINUTE) {
85 | return $this;
86 | }
87 |
88 | if ($this->unit->getUnit() == TimeUnit::SECOND) {
89 | return new Duration(floor($this->value / self::NB_SECOND_PER_MINUTE), TimeUnit::minute());
90 | }
91 |
92 | if ($this->unit->getUnit() == TimeUnit::HOUR) {
93 | return new Duration(self::NB_MINUTE_PER_HOUR * $this->value, TimeUnit::minute());
94 | }
95 |
96 | if ($this->unit->getUnit() == TimeUnit::DAY) {
97 | return new Duration(self::NB_MINUTE_PER_DAY * $this->value, TimeUnit::minute());
98 | }
99 |
100 | if ($this->unit->getUnit() == TimeUnit::WEEK) {
101 | return new Duration(self::NB_MINUTE_PER_WEEK * $this->value, TimeUnit::minute());
102 | }
103 |
104 | if (TimeUnit::MONTH === $this->unit->getUnit() || TimeUnit::YEAR === $this->unit->getUnit()) {
105 | return $this->toDays()->toMinutes();
106 | }
107 |
108 | throw new \LogicException('Can\'t convert duration.');
109 | }
110 |
111 | public function toHours()
112 | {
113 | if ($this->unit->getUnit() == TimeUnit::HOUR) {
114 | return $this;
115 | }
116 |
117 | if ($this->unit->getUnit() == TimeUnit::SECOND) {
118 | return new Duration(floor($this->value / (self::NB_SECOND_PER_HOUR)), TimeUnit::hour());
119 | }
120 |
121 | if ($this->unit->getUnit() == TimeUnit::MINUTE) {
122 | return new Duration(floor($this->value / self::NB_MINUTE_PER_HOUR), TimeUnit::hour());
123 | }
124 |
125 | if ($this->unit->getUnit() == TimeUnit::DAY) {
126 | return new Duration(self::NB_HOUR_PER_DAY * $this->value, TimeUnit::hour());
127 | }
128 |
129 | if ($this->unit->getUnit() == TimeUnit::WEEK) {
130 | return new Duration(self::NB_HOUR_PER_WEEK * $this->value, TimeUnit::hour());
131 | }
132 |
133 | if (TimeUnit::MONTH === $this->unit->getUnit() || TimeUnit::YEAR === $this->unit->getUnit()) {
134 | return $this->toDays()->toHours();
135 | }
136 |
137 | throw new \LogicException('can\'t convert some years to hours.');
138 | }
139 |
140 | public function toDays()
141 | {
142 | if ($this->unit->getUnit() == TimeUnit::DAY) {
143 | return $this;
144 | }
145 |
146 | if ($this->unit->getUnit() == TimeUnit::SECOND) {
147 | return new Duration(floor($this->value / self::NB_SECOND_PER_DAY), TimeUnit::day());
148 | }
149 |
150 | if ($this->unit->getUnit() == TimeUnit::MINUTE) {
151 | return new Duration(floor($this->value / self::NB_MINUTE_PER_DAY), TimeUnit::day());
152 | }
153 |
154 | if ($this->unit->getUnit() == TimeUnit::HOUR) {
155 | return new Duration(floor($this->value/ self::NB_HOUR_PER_DAY), TimeUnit::day());
156 | }
157 |
158 | if ($this->unit->getUnit() == TimeUnit::WEEK) {
159 | return new Duration(self::NB_DAY_PER_WEEK * $this->value, TimeUnit::day());
160 | }
161 |
162 | if ($this->unit->getUnit() == TimeUnit::MONTH) {
163 | $firstMonth = new \DateTime();
164 | $firstMonth->setDate($this->year, $this->month, 1);
165 | $endMonth = new \DateTime();
166 | $endMonth->setDate($this->year, $this->month, 1);
167 | $endMonth->add(new \DateInterval('P'.$this->value.'M'));
168 | $interval = $firstMonth->diff($endMonth);
169 |
170 | return new Duration($interval->days, TimeUnit::day());
171 | }
172 |
173 | if ($this->unit->getUnit() == TimeUnit::YEAR) {
174 | $firstYear = new \DateTime();
175 | $firstYear->setDate($this->year, 1, 1);
176 | $endYear = new \DateTime();
177 | $endYear->setDate($this->year, 1, 1);
178 | $endYear->add(new \DateInterval('P'.$this->value.'Y'));
179 | $interval = $firstYear->diff($endYear);
180 |
181 | return new Duration($interval->days, TimeUnit::day());
182 | }
183 |
184 | throw new \LogicException('can\'t convert some months or years to days.');
185 | }
186 |
187 | public function toWeeks()
188 | {
189 | if ($this->unit->getUnit() == TimeUnit::WEEK) {
190 | return $this;
191 | }
192 |
193 | if ($this->unit->getUnit() == TimeUnit::SECOND) {
194 | return new Duration(floor($this->value / self::NB_SECOND_PER_WEEK), TimeUnit::week());
195 | }
196 |
197 | if ($this->unit->getUnit() == TimeUnit::MINUTE) {
198 | return new Duration(floor($this->value / self::NB_MINUTE_PER_WEEK), TimeUnit::week());
199 | }
200 |
201 | if ($this->unit->getUnit() == TimeUnit::HOUR) {
202 | return new Duration(floor($this->value / self::NB_HOUR_PER_WEEK), TimeUnit::week());
203 | }
204 |
205 | if ($this->unit->getUnit() == TimeUnit::DAY) {
206 | return new Duration(floor($this->value / self::NB_DAY_PER_WEEK), TimeUnit::week());
207 | }
208 |
209 | throw new \LogicException('can\'t convert some months or years to weeks.');
210 | }
211 | }
212 |
--------------------------------------------------------------------------------