diff --git a/DataStorage/Cache/Connection/FileCache.php b/DataStorage/Cache/Connection/FileCache.php index 31b3a2db0..bca5545c9 100644 --- a/DataStorage/Cache/Connection/FileCache.php +++ b/DataStorage/Cache/Connection/FileCache.php @@ -240,7 +240,7 @@ class FileCache extends ConnectionAbstract } elseif ($type === CacheValueType::_SERIALIZABLE) { return \get_class($value) . self::DELIM . $value->serialize(); } elseif ($type === CacheValueType::_JSONSERIALIZABLE) { - return \get_class($value) . self::DELIM . $value->jsonSerialize(); + return \get_class($value) . self::DELIM . ((string) \json_encode($value->jsonSerialize())); } elseif ($type === CacheValueType::_NULL) { return ''; } @@ -279,7 +279,7 @@ class FileCache extends ConnectionAbstract return null; } - $created = Directory::created($path)->getTimestamp(); + $created = File::created($path)->getTimestamp(); $now = \time(); if ($expire >= 0 && $created + $expire < $now) { @@ -300,7 +300,7 @@ class FileCache extends ConnectionAbstract } $cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1)); - $cacheExpire = ($cacheExpire === false) ? $created : (int) $cacheExpire; + $cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire; if ($cacheExpire >= 0 && $created + $cacheExpire < $now) { $this->delete($key); @@ -324,43 +324,37 @@ class FileCache extends ConnectionAbstract */ private function reverseValue(int $type, string $raw, int $expireEnd) { - $value = null; - switch ($type) { case CacheValueType::_INT: - $value = (int) \substr($raw, $expireEnd + 1); - break; + return (int) \substr($raw, $expireEnd + 1); case CacheValueType::_FLOAT: - $value = (float) \substr($raw, $expireEnd + 1); - break; + return (float) \substr($raw, $expireEnd + 1); case CacheValueType::_BOOL: - $value = (bool) \substr($raw, $expireEnd + 1); - break; + return (bool) \substr($raw, $expireEnd + 1); case CacheValueType::_STRING: - $value = \substr($raw, $expireEnd + 1); - break; + return \substr($raw, $expireEnd + 1); case CacheValueType::_ARRAY: $array = \substr($raw, $expireEnd + 1); - $value = \json_decode($array === false ? '[]' : $array, true); - break; + return \json_decode($array === false ? '[]' : $array, true); case CacheValueType::_NULL: - $value = null; - break; - case CacheValueType::_SERIALIZABLE: + return null; case CacheValueType::_JSONSERIALIZABLE: + case CacheValueType::_SERIALIZABLE: $namespaceStart = (int) \strpos($raw, self::DELIM, $expireEnd); $namespaceEnd = (int) \strpos($raw, self::DELIM, $namespaceStart + 1); - $namespace = \substr($raw, $namespaceStart, $namespaceEnd); + $namespace = \substr($raw, $namespaceStart + 1, $namespaceEnd - $namespaceStart - 1); if ($namespace === false) { return null; } - $value = $namespace::unserialize(\substr($raw, $namespaceEnd + 1)); - break; - } + $obj = new $namespace(); + $obj->unserialize(\substr($raw, $namespaceEnd + 1)); - return $value; + return $obj; + default: + return null; + } } /** @@ -373,14 +367,18 @@ class FileCache extends ConnectionAbstract } $path = $this->getPath($key); - if ($expire < 0 && File::exists($path)) { + if (!File::exists($path)) { + return true; + } + + if ($expire < 0) { File::delete($path); return true; } if ($expire >= 0) { - $created = Directory::created(Directory::sanitize($key, self::SANITIZE))->getTimestamp(); + $created = File::created($path)->getTimestamp(); $now = \time(); $raw = \file_get_contents($path); @@ -388,26 +386,15 @@ class FileCache extends ConnectionAbstract return false; } - $expireStart = (int) \strpos($raw, self::DELIM); - $expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1); - - if ($expireStart < 0 || $expireEnd < 0) { - return false; - } - - $cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1)); - $cacheExpire = ($cacheExpire === false) ? $created : (int) $cacheExpire; + $cacheExpire = $this->getExpire($raw); + $cacheExpire = ($cacheExpire === -1) ? $created : (int) $cacheExpire; if ($cacheExpire >= 0 && $created + $cacheExpire < $now) { - $this->delete($key); - - return false; + return $this->delete($key); } - if ($cacheExpire >= 0 && $created + $cacheExpire > $now) { - File::delete($path); - - return true; + if ($cacheExpire >= 0 && \abs($now - $created) > $expire) { + return $this->delete($key); } } diff --git a/DataStorage/Session/HttpSession.php b/DataStorage/Session/HttpSession.php index bcf7a84b7..6ea44a1b4 100644 --- a/DataStorage/Session/HttpSession.php +++ b/DataStorage/Session/HttpSession.php @@ -76,10 +76,6 @@ class HttpSession implements SessionInterface */ public function __construct(int $liftetime = 3600, $sid = false, int $inactivityInterval = 0) { - if ($this->isLocked) { - throw new LockException('HttpSession'); - } - if (\session_id()) { \session_write_close(); } diff --git a/Stdlib/Queue/PriorityQueue.php b/Stdlib/Queue/PriorityQueue.php index 0e30b1a5e..c84ae88a6 100644 --- a/Stdlib/Queue/PriorityQueue.php +++ b/Stdlib/Queue/PriorityQueue.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace phpOMS\Stdlib\Queue; +use phpOMS\Stdlib\Base\Exception\InvalidEnumValue; + /** * Priority queue class. * @@ -47,6 +49,10 @@ class PriorityQueue implements \Countable, \Serializable */ public function __construct(int $type = PriorityMode::FIFO) { + if (!PriorityMode::isValidValue($type)) { + throw new InvalidEnumValue($type); + } + $this->type = $type; } @@ -112,7 +118,7 @@ class PriorityQueue implements \Countable, \Serializable case PriorityMode::LOWEST: return $this->getInsertLowest($priority); default: - throw new \InvalidArgumentException(); + throw new InvalidEnumValue($this->type); } } diff --git a/Utils/StringUtils.php b/Utils/StringUtils.php index 66f4851b4..d7c8406f3 100644 --- a/Utils/StringUtils.php +++ b/Utils/StringUtils.php @@ -413,7 +413,7 @@ final class StringUtils } elseif (\is_int($element) || \is_float($element)) { return (string) $element; } elseif (\is_bool($element)) { - return (string) $element; + return $element ? '1' : '0'; } elseif ($element === null) { return null; } elseif ($element instanceof \DateTime) { diff --git a/tests/DataStorage/Cache/Connection/FileCacheJsonSerializable.php b/tests/DataStorage/Cache/Connection/FileCacheJsonSerializable.php new file mode 100644 index 000000000..aa2ccd209 --- /dev/null +++ b/tests/DataStorage/Cache/Connection/FileCacheJsonSerializable.php @@ -0,0 +1,29 @@ +val = \json_decode($val, true); + } +} \ No newline at end of file diff --git a/tests/DataStorage/Cache/Connection/FileCacheSerializable.php b/tests/DataStorage/Cache/Connection/FileCacheSerializable.php new file mode 100644 index 000000000..ad4b305e4 --- /dev/null +++ b/tests/DataStorage/Cache/Connection/FileCacheSerializable.php @@ -0,0 +1,29 @@ +val = $val; + } +} \ No newline at end of file diff --git a/tests/DataStorage/Cache/Connection/FileCacheTest.php b/tests/DataStorage/Cache/Connection/FileCacheTest.php index de1cd7d9b..41bfc4992 100644 --- a/tests/DataStorage/Cache/Connection/FileCacheTest.php +++ b/tests/DataStorage/Cache/Connection/FileCacheTest.php @@ -87,19 +87,25 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase $cache->set('key6', ['asdf', 1, true, 2.3]); // 7 self::assertEquals(['asdf', 1, true, 2.3], $cache->get('key6')); + $cache->set('key7', new FileCacheSerializable()); // 8 + self::assertEquals('abc', $cache->get('key7')->val); + + $cache->set('key8', new FileCacheJsonSerializable()); // 9 + self::assertEquals('abc', $cache->get('key8')->val); + self::assertTrue($cache->replace('key4', 5)); self::assertFalse($cache->replace('keyInvalid', 5)); self::assertEquals(5, $cache->get('key4')); - self::assertTrue($cache->delete('key4')); // 6 - self::assertFalse($cache->delete('keyInvalid')); + self::assertTrue($cache->delete('key4')); // 8 + self::assertTrue($cache->delete('keyInvalid')); self::assertEquals(null, $cache->get('key4')); self::assertEquals( [ 'status' => CacheStatus::OK, - 'count' => 6, - 'size' => 70, + 'count' => 8, + 'size' => 220, ], $cache->stats() ); @@ -107,8 +113,6 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase self::assertTrue($cache->flushAll()); self::assertEquals(null, $cache->get('key5')); - $cache->flushAll(); - self::assertEquals( [ 'status' => CacheStatus::OK, @@ -123,6 +127,49 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase } } + public function testExpire() + { + if (\file_exists(__DIR__ . '/Cache')) { + \rmdir(__DIR__ . '/Cache'); + } + + $cache = new FileCache(__DIR__ . '/Cache'); + + $cache->flushAll(); + + $cache->set('key1', 'testVal', 1); + self::assertEquals('testVal', $cache->get('key1')); + + $cache->set('key2', 'testVal2', 1); + self::assertEquals('testVal2', $cache->get('key2', 1)); + sleep(3); + self::assertEquals(null, $cache->get('key2', 1)); + + $cache->set('key3', 'testVal3', 1); + self::assertEquals('testVal3', $cache->get('key3', 1)); + sleep(3); + self::assertEquals(null, $cache->get('key3', 1)); + + $cache->set('key4', 'testVal4', 1); + self::assertFalse($cache->delete('key4', 0)); + sleep(3); + self::assertTrue($cache->delete('key4', 1)); + + $cache->set('key5', 'testVal5', 10000); + sleep(3); + self::assertFalse($cache->delete('key5', 1000000)); + self::assertTrue($cache->delete('key5', 1)); + + $cache->set('key6', 'testVal6', 1); + sleep(2); + + $cache->flush(0); + + if (\file_exists(__DIR__ . '/Cache')) { + \rmdir(__DIR__ . '/Cache'); + } + } + public function testBadCacheStatus() { if (\file_exists(__DIR__ . '/Cache')) { @@ -140,6 +187,7 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase self::assertFalse($cache->replace('key1', 5)); self::assertFalse($cache->delete('key1')); self::assertFalse($cache->flushAll()); + self::assertFalse($cache->flush()); self::assertEquals([], $cache->stats()); if (\file_exists(__DIR__ . '/Cache')) { diff --git a/tests/DataStorage/Session/HttpSessionTest.php b/tests/DataStorage/Session/HttpSessionTest.php index 57892889a..0e1e3e39f 100644 --- a/tests/DataStorage/Session/HttpSessionTest.php +++ b/tests/DataStorage/Session/HttpSessionTest.php @@ -41,5 +41,8 @@ class HttpSessionTest extends \PHPUnit\Framework\TestCase $session->setSID('abc'); self::assertEquals('abc', $session->getSID()); + + $session->lock(); + self::assertTrue($session->isLocked()); } } diff --git a/tests/Stdlib/Queue/PriorityQueueTest.php b/tests/Stdlib/Queue/PriorityQueueTest.php index ba690e21a..e8f4131b3 100644 --- a/tests/Stdlib/Queue/PriorityQueueTest.php +++ b/tests/Stdlib/Queue/PriorityQueueTest.php @@ -51,6 +51,11 @@ class PriorityQueueTest extends \PHPUnit\Framework\TestCase $queue->setPriority($id1, 3); self::assertEquals(3, $queue->get($id1)['priority']); + + $queue2 = new PriorityQueue(); + $queue2->unserialize($queue->serialize()); + + self::assertEquals($queue->serialize(), $queue2->serialize()); } public function testFIFO() @@ -205,4 +210,12 @@ class PriorityQueueTest extends \PHPUnit\Framework\TestCase self::assertFalse($queue->delete($id2)); self::assertEquals(1, $queue->count()); } + + /** + * @expectedException \phpOMS\Stdlib\Base\Exception\InvalidEnumValue + */ + public function testInvalidPriority() + { + $queue = new PriorityQueue(99999); + } } diff --git a/tests/Utils/StringUtilsTest.php b/tests/Utils/StringUtilsTest.php index 9802f0823..0f0cc1d74 100644 --- a/tests/Utils/StringUtilsTest.php +++ b/tests/Utils/StringUtilsTest.php @@ -79,4 +79,44 @@ class StringUtilsTest extends \PHPUnit\Framework\TestCase self::assertEquals(4, StringUtils::countCharacterFromStart(' Test string', ' ')); self::assertEquals(0, StringUtils::countCharacterFromStart(' Test string', 's')); } + + public function testStringify() + { + self::assertEquals('"abc"', StringUtils::stringify(new class implements \JsonSerializable { + public function jsonSerialize() + { + return 'abc'; + } + })); + + self::assertEquals('["abc"]', StringUtils::stringify(['abc'])); + + self::assertEquals('abc', StringUtils::stringify(new class implements \Serializable { + public function serialize() + { + return 'abc'; + } + + public function unserialize($val) + { + } + })); + + self::assertEquals('abc', StringUtils::stringify('abc')); + self::assertEquals('1', StringUtils::stringify(1)); + self::assertEquals('1.1', StringUtils::stringify(1.1)); + self::assertEquals('1', StringUtils::stringify(true)); + self::assertEquals('0', StringUtils::stringify(false)); + self::assertEquals(null, StringUtils::stringify(null)); + + $date = new \DateTime('now'); + self::assertEquals($date->format('Y-m-d H:i:s'), StringUtils::stringify($date)); + + self::assertEquals('abc', StringUtils::stringify(new class { + public function __toString() + { + return 'abc'; + } + })); + } }