Skip to content

Commit 9df53be

Browse files
authored
Merge pull request #750 from DirectoryTree/feature-745
Feature 745 - [Feature] Support for LDAP milliseconds format
2 parents d66344a + 94884bd commit 9df53be

File tree

8 files changed

+44
-30
lines changed

8 files changed

+44
-30
lines changed

src/Models/Attributes/Timestamp.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,12 @@ public function toDateTime(mixed $value): Carbon|int|false
127127
*/
128128
protected function convertLdapTimeToDateTime(string $value): DateTime|false
129129
{
130-
return DateTime::createFromFormat(
131-
str_contains($value, 'Z') ? 'YmdHis\Z' : 'YmdHisT',
132-
$value
133-
);
130+
return DateTime::createFromFormat(match (true) {
131+
str_ends_with($value, '.000Z') => 'YmdHis.000\Z',
132+
str_ends_with($value, '.0Z') => 'YmdHis.0\Z',
133+
str_ends_with($value, 'Z') => 'YmdHis\Z',
134+
default => 'YmdHisT',
135+
}, $value);
134136
}
135137

136138
/**
@@ -139,7 +141,9 @@ protected function convertLdapTimeToDateTime(string $value): DateTime|false
139141
protected function convertDateTimeToLdapTime(DateTime $date): string
140142
{
141143
return $date->format(
142-
$date->getOffset() == 0 ? 'YmdHis\Z' : 'YmdHisO'
144+
$date->getOffset() == 0
145+
? 'YmdHis\Z'
146+
: 'YmdHisO'
143147
);
144148
}
145149

@@ -148,11 +152,10 @@ protected function convertDateTimeToLdapTime(DateTime $date): string
148152
*/
149153
protected function convertWindowsTimeToDateTime(string $value): DateTime|false
150154
{
151-
return DateTime::createFromFormat(
152-
str_contains($value, '0Z') ? 'YmdHis.0\Z' : 'YmdHis.0T',
153-
$value,
154-
new DateTimeZone('UTC')
155-
);
155+
return DateTime::createFromFormat(match (true) {
156+
str_ends_with($value, '.0Z') => 'YmdHis.0\Z',
157+
default => 'YmdHis.0T'
158+
}, $value, new DateTimeZone('UTC'));
156159
}
157160

158161
/**
@@ -161,7 +164,9 @@ protected function convertWindowsTimeToDateTime(string $value): DateTime|false
161164
protected function convertDateTimeToWindows(DateTime $date): string
162165
{
163166
return $date->format(
164-
$date->getOffset() == 0 ? 'YmdHis.0\Z' : 'YmdHis.0O'
167+
$date->getOffset() == 0
168+
? 'YmdHis.0\Z'
169+
: 'YmdHis.0O'
165170
);
166171
}
167172

tests/Unit/Models/Attributes/TimestampTest.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace LdapRecord\Tests\Unit\Models\Attributes;
44

55
use DateTime;
6+
use DateTimeZone;
67
use LdapRecord\LdapRecordException;
78
use LdapRecord\Models\Attributes\Timestamp;
89
use LdapRecord\Tests\TestCase;
@@ -11,7 +12,9 @@ class TimestampTest extends TestCase
1112
{
1213
protected int $unixTimestamp = 1601605329;
1314

14-
protected string $utcLdapTimestamp = '20201002021244Z';
15+
protected string $utcLdapTimestamp = '20201002021240Z';
16+
17+
protected string $utcLdapMillisecondsTimestamp = '20231106080944.000Z';
1518

1619
protected string $offsetLdapTimestamp = '20201002021244-0500';
1720

@@ -44,7 +47,7 @@ public function test_dates_can_be_converted_to_ldap_type()
4447
$date = new DateTime;
4548
$this->assertEquals($date->format('YmdHis\Z'), $timestamp->fromDateTime($date));
4649

47-
$date = (new DateTime)->setTimezone(new \DateTimeZone('EST'));
50+
$date = (new DateTime)->setTimezone(new DateTimeZone('EST'));
4851
$this->assertEquals($date->format('YmdHis').'-0500', $timestamp->fromDateTime($date));
4952
}
5053

@@ -55,7 +58,7 @@ public function test_dates_can_be_converted_to_windows_type()
5558
$date = new DateTime;
5659
$this->assertEquals($date->format('YmdHis.0\Z'), $timestamp->fromDateTime($date));
5760

58-
$date = (new DateTime)->setTimezone(new \DateTimeZone('EST'));
61+
$date = (new DateTime)->setTimezone(new DateTimeZone('EST'));
5962
$this->assertEquals($date->format('YmdHis.0').'-0500', $timestamp->fromDateTime($date));
6063
}
6164

@@ -76,13 +79,17 @@ public function test_ldap_type_can_be_converted_to_date()
7679

7780
$this->assertInstanceOf(DateTime::class, $datetime);
7881
$this->assertEquals('UTC', $datetime->timezone->getName());
79-
$this->assertEquals('Fri Oct 02 2020 02:12:44 GMT+0000', $datetime->toString());
82+
$this->assertEquals('Fri Oct 02 2020 02:12:40 GMT+0000', $datetime->toString());
8083

8184
$datetime = $timestamp->toDateTime($this->offsetLdapTimestamp);
8285

8386
$this->assertInstanceOf(DateTime::class, $datetime);
8487
$this->assertEquals('-05:00', $datetime->timezone->getName());
8588
$this->assertEquals('Fri Oct 02 2020 02:12:44 GMT-0500', $datetime->toString());
89+
90+
$datetime = $timestamp->toDateTime($this->utcLdapMillisecondsTimestamp);
91+
$this->assertEquals('UTC', $datetime->timezone->getName());
92+
$this->assertEquals('Mon Nov 06 2023 08:09:44 GMT+0000', $datetime->toString());
8693
}
8794

8895
public function test_windows_type_can_be_converted_to_date()

tests/Unit/Models/ModelAccessorMutatorTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Carbon\Carbon;
66
use DateTime;
7+
use DateTimeInterface;
78
use LdapRecord\Models\Attributes\Timestamp;
89
use LdapRecord\Models\Model;
910
use LdapRecord\Tests\TestCase;
@@ -20,7 +21,7 @@ public function test_model_uses_accessor()
2021

2122
$this->assertEquals(['bar'], $model->getAttributes()['foo']);
2223
$this->assertEquals(['barbaz'], $model->toArray()['foo']);
23-
$this->assertEquals([$date->format(\DateTimeInterface::ISO8601)], $model->toArray()['createtimestamp']);
24+
$this->assertEquals([$date->format(DateTimeInterface::ISO8601)], $model->toArray()['createtimestamp']);
2425
$this->assertEquals('barbaz', $model->foo);
2526
$this->assertEquals('barbaz', $model->getAttribute('foo'));
2627
$this->assertEquals('barbaz', $model->getFirstAttribute('foo'));

tests/Unit/Models/ModelAttributeCastTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace LdapRecord\Tests\Unit\Models;
44

5+
use DateTime;
56
use LdapRecord\Models\Model;
67
use LdapRecord\Query\Collection;
78
use LdapRecord\Tests\TestCase;
@@ -174,7 +175,7 @@ public function test_ldap_datetime_attributes_are_casted()
174175

175176
// Reverse casting
176177

177-
$model->ldapDateTime = new \DateTime('2020-10-02 02:12:44');
178+
$model->ldapDateTime = new DateTime('2020-10-02 02:12:44');
178179
$this->assertEquals($model->getRawAttribute('ldapDateTime'), ['20201002021244Z']);
179180
}
180181

@@ -186,7 +187,7 @@ public function test_windows_datetime_attributes_are_casted()
186187

187188
// Reverse casting
188189

189-
$model->windowsDateTime = new \DateTime('2020-10-02 02:16:18');
190+
$model->windowsDateTime = new DateTime('2020-10-02 02:16:18');
190191
$this->assertEquals($model->getRawAttribute('windowsDateTime'), ['20201002021618.0Z']);
191192
}
192193

@@ -198,7 +199,7 @@ public function test_windows_int_datetime_attributes_are_casted()
198199

199200
// Reverse casting
200201

201-
$model->windowsIntDateTime = new \DateTime('2020-10-02 02:22:09');
202+
$model->windowsIntDateTime = new DateTime('2020-10-02 02:22:09');
202203
$this->assertEquals($model->getRawAttribute('windowsIntDateTime'), ['132460789290000000']);
203204
}
204205

tests/Unit/Models/ModelSerializationTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
class ModelSerializationTest extends TestCase
1414
{
15-
public function testModelWithTimestampsCanBeSerializedAndEncoded()
15+
public function test_model_with_timestamps_can_be_serialized_and_encoded()
1616
{
1717
$whenchanged = (new Timestamp('windows'))->fromDateTime(new DateTime);
1818
$lastlogon = (new Timestamp('windows-int'))->fromDateTime(new DateTime);
@@ -43,7 +43,7 @@ public function testModelWithTimestampsCanBeSerializedAndEncoded()
4343
$this->assertEquals($model->getAttributes()['whenchanged'], $unserializedAndUnencoded->getAttributes()['whenchanged']);
4444
}
4545

46-
public function testModelWithBinaryGuidAndSidCanBeSerializedAndEncoded()
46+
public function test_model_with_binary_guid_and_sid_can_be_serialized_and_encoded()
4747
{
4848
$guid = new Guid('2bba564a-4f95-4cb0-97b0-94c0e3458621');
4949
$sid = new Sid('S-1-5-21-1004336348-1177238915-682003330-512');

tests/Unit/Testing/AuthGuardFakeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class AuthGuardFakeTest extends TestCase
1111
{
12-
public function testBindAsConfiguredUserAlwaysReturnsNull()
12+
public function test_bind_as_configured_user_always_returns_null()
1313
{
1414
$guard = new AuthGuardFake(new LdapFake, new DomainConfiguration);
1515

tests/Unit/Testing/ConnectionFakeTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
class ConnectionFakeTest extends TestCase
99
{
10-
public function testMake()
10+
public function test_make()
1111
{
1212
$this->assertInstanceOf(ConnectionFake::class, ConnectionFake::make());
1313
}
1414

15-
public function testMakeWithConfig()
15+
public function test_make_with_config()
1616
{
1717
$fake = $fake = ConnectionFake::make([
1818
'hosts' => ['foo', 'bar'],
@@ -25,14 +25,14 @@ public function testMakeWithConfig()
2525
$this->assertTrue($config->get('use_tls'));
2626
}
2727

28-
public function testMakeWithCustomLdapFake()
28+
public function test_make_with_custom_ldap_fake()
2929
{
3030
$fake = ConnectionFake::make([], ExtendedLdapFake::class);
3131

3232
$this->assertInstanceOf(ExtendedLdapFake::class, $fake->getLdapConnection());
3333
}
3434

35-
public function testActingAsWithModel()
35+
public function test_acting_as_with_model()
3636
{
3737
$fake = ConnectionFake::make();
3838

@@ -49,7 +49,7 @@ public function testActingAsWithModel()
4949
$this->assertTrue($fake->auth()->attempt($user->getDn(), 'secret', $stayBound = true));
5050
}
5151

52-
public function testActingAsWithDn()
52+
public function test_acting_as_with_dn()
5353
{
5454
$fake = ConnectionFake::make();
5555

tests/Unit/Testing/DirectoryFakeTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212

1313
class DirectoryFakeTest extends TestCase
1414
{
15-
public function testSetupThrowsExceptionWhenNoConnectionHasBeenConfigured()
15+
public function test_setup_throws_exception_when_no_connection_has_been_configured()
1616
{
1717
$this->expectException(ContainerException::class);
1818

1919
DirectoryFake::setup();
2020
}
2121

22-
public function testSetupCreatesConnectedFakeConnectionAndLdapInstance()
22+
public function test_setup_creates_connected_fake_connection_and_ldap_instance()
2323
{
2424
Container::addConnection(new Connection);
2525

@@ -31,7 +31,7 @@ public function testSetupCreatesConnectedFakeConnectionAndLdapInstance()
3131
$this->assertInstanceOf(LdapFake::class, $fake->getLdapConnection());
3232
}
3333

34-
public function testTearDownFlushesContainer()
34+
public function test_tear_down_flushes_container()
3535
{
3636
Container::addConnection(new Connection);
3737

0 commit comments

Comments
 (0)