{"action":"created","comment":{"url":"https://api.github.com/repos/zendframework/zend-cache/pulls/comments/32379258","id":32379258,"diff_hunk":"@@ -458,4 +479,58 @@ protected function internalGetCapabilities()\n \n         return $this->capabilities;\n     }\n+\n+    /**\n+     * {@inheritDoc}\n+     *\n+     * @throws Exception\\ExceptionInterface\n+     */\n+    protected function internalGetMetadata(& $normalizedKey)\n+    {\n+        if (!$this->internalHasItem($normalizedKey)) {\n+            return false;\n+        }\n+\n+        $redis = $this->getRedisResource();\n+        try {\n+\n+            /**\n+             * Remaining ttl of an item, in seconds\n+             * In redis 2.6, the command return -1 if the key does not exist\n+             * In redis > 2.8, the command return -2 if the key does not exist, -1 if the key exists but has no associated expire\n+             */\n+            $majorVersion = $this->resourceManager->getMajorVersion($this->resourceId);\n+            if ($majorVersion >= 2.8) {\n+                $pttl = $redis->pttl($this->namespacePrefix . $normalizedKey);\n+                switch ($pttl) {\n+                    case -2: $ttl = false; break;\n+                    case -1:\n+                    case 0: $ttl = null; break;\n+                    default: $ttl = $pttl / 1000;\n+                }\n+            }\n+            else if ($majorVersion >= 2.6) {\n+                $pttl = $redis->pttl($this->namespacePrefix . $normalizedKey);\n+                switch ($pttl) {\n+                    case -1: $ttl = false; break;\n+                    case 0: $ttl = null; break;\n+                    default: $ttl = $pttl / 1000;\n+                }\n+            }\n+            else if ($majorVersion >= 2) {\n+                $ttl = $redis->ttl($this->namespacePrefix . $normalizedKey);\n+                $ttl = $ttl > 0 ? $ttl : null;\n+            }\n+            else {\n+                $ttl = false;\n+            }","path":"src/Storage/Adapter/Redis.php","position":85,"original_position":85,"commit_id":"3a7e5c1c84e1eb7834d0ac1b06850821c19d1760","original_commit_id":"3a7e5c1c84e1eb7834d0ac1b06850821c19d1760","user":{"login":"marc-mabe","id":302689,"avatar_url":"https://avatars.githubusercontent.com/u/302689?v=3","gravatar_id":"","url":"https://api.github.com/users/marc-mabe","html_url":"https://github.com/marc-mabe","followers_url":"https://api.github.com/users/marc-mabe/followers","following_url":"https://api.github.com/users/marc-mabe/following{/other_user}","gists_url":"https://api.github.com/users/marc-mabe/gists{/gist_id}","starred_url":"https://api.github.com/users/marc-mabe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marc-mabe/subscriptions","organizations_url":"https://api.github.com/users/marc-mabe/orgs","repos_url":"https://api.github.com/users/marc-mabe/repos","events_url":"https://api.github.com/users/marc-mabe/events{/privacy}","received_events_url":"https://api.github.com/users/marc-mabe/received_events","type":"User","site_admin":false},"body":"This looks better but now you return an array with `ttl=false` in this case instead of `return false` and the check for `if (!$this->internalHasItem($normalizedKey)) { return false; }` can be removed.\r\n\r\nAlso I see that redis < 2 doesn't support this feature so this have to be reflect in `getCapabilities()`, too.\r\nOnly on redis < 2 you have to check for item existence:\r\n\r\nI also don't see a difference of TTL = 0 and expired. It looks like the 0 means the item exist but have a remaining TTL of 0 seconds so it will be expire in the very near future but I didn't test it and couldn't find information quickly.\r\n\r\nThis is a fast coded version I think of but needs testing.\r\n```php\r\nprotected function internalGetMetadata(& $normalizedKey)\r\n{\r\n    $redis    = $this->getRedisResource();\r\n    $metadata = [];\r\n\r\n    try {\r\n        $redisVersion = $this->resourceManager->getMajorVersion($this->resourceId);\r\n\r\n        // redis >= 2.8\r\n        // The command 'pttl' returns -2 if the item does not exist\r\n        // and -1 if the item has no associated expire\r\n        if (version_compare($redisVersion, '2.8',  '>=') {\r\n            $pttl = $redis->pttl($this->namespacePrefix . $normalizedKey);\r\n            if ($pttl <= -2) {\r\n                return false;\r\n            }\r\n            $metadata['ttl'] = ($pttl == -1) ? null : $pttl / 1000;\r\n\r\n        // redis >= 2.6\r\n        // The command 'pttl' returns -1 if the item does not exist\r\n        } elseif (version_compare($redisVersion, '2.6', '>=') {\r\n            if ($pttl <= -1) {\r\n                return false;\r\n            }\r\n            $metadata['ttl'] = $pttl / 1000;\r\n\r\n        // redis >= 2\r\n        // The command 'pttl' is not supported but 'ttl'\r\n        // The command 'ttl' returns 0 if the item does not exist same as if the item is going to be expired\r\n        // NOTE: In case of ttl=0 we return false because the item is goning to be expired in a very near future\r\n        //       and then doesn't exist any more\r\n        } elseif (version_compare($redisVersion, '2', '>=')) {\r\n            $ttl = $redis->ttl($this->namespacePrefix . $normalizedKey)\r\n            if ($ttl <= 0) {\r\n                return false;\r\n            }\r\n            $metadata['ttl'] = $ttl;\r\n\r\n        // redis < 2\r\n        // The commands 'pttl' and 'ttl' are not supported\r\n        // but item existence have to be checked\r\n        } elseif (!$this->internalHasItem($normalizedKey)) {\r\n            return false;\r\n        }\r\n\r\n    } catch (RedisResourceException $e) {\r\n        throw new Exception\\RuntimeException($redis->getLastError(), $e->getCode(), $e);\r\n    }\r\n\r\n    return $metadata;\r\n}\r\n```\r\n\r\nAs you see on redis < 2 this method isn't supported and will not be present in the returned metadata array so the redis version have to be checked also on get capabilities.\r\n","created_at":"2015-06-14T12:49:21Z","updated_at":"2015-06-14T12:49:21Z","html_url":"https://github.com/zendframework/zend-cache/pull/10#discussion_r32379258","pull_request_url":"https://api.github.com/repos/zendframework/zend-cache/pulls/10","_links":{"self":{"href":"https://api.github.com/repos/zendframework/zend-cache/pulls/comments/32379258"},"html":{"href":"https://github.com/zendframework/zend-cache/pull/10#discussion_r32379258"},"pull_request":{"href":"https://api.github.com/repos/zendframework/zend-cache/pulls/10"}}},"pull_request":{"url":"https://api.github.com/repos/zendframework/zend-cache/pulls/10","id":37629519,"html_url":"https://github.com/zendframework/zend-cache/pull/10","diff_url":"https://github.com/zendframework/zend-cache/pull/10.diff","patch_url":"https://github.com/zendframework/zend-cache/pull/10.patch","issue_url":"https://api.github.com/repos/zendframework/zend-cache/issues/10","number":10,"state":"open","locked":false,"title":"Set ttl to specific cache key for Redis Storage Adapter","user":{"login":"pensiero","id":2010696,"avatar_url":"https://avatars.githubusercontent.com/u/2010696?v=3","gravatar_id":"","url":"https://api.github.com/users/pensiero","html_url":"https://github.com/pensiero","followers_url":"https://api.github.com/users/pensiero/followers","following_url":"https://api.github.com/users/pensiero/following{/other_user}","gists_url":"https://api.github.com/users/pensiero/gists{/gist_id}","starred_url":"https://api.github.com/users/pensiero/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pensiero/subscriptions","organizations_url":"https://api.github.com/users/pensiero/orgs","repos_url":"https://api.github.com/users/pensiero/repos","events_url":"https://api.github.com/users/pensiero/events{/privacy}","received_events_url":"https://api.github.com/users/pensiero/received_events","type":"User","site_admin":false},"body":"- Implemented the `internalTouchItem` method inside `Storage\\Adapter\\Redis` that allow to touch a Redis item.\r\n- Implemented the `_ttl` metadata, that return the remaining tll of a specific key\r\n\r\nThanks to @marc-mabe to help me understanding what to do!\r\n\r\nRefer to #5, I have created a new PR to clean my code from other local branches that was creating troubles.","created_at":"2015-06-13T18:54:57Z","updated_at":"2015-06-14T12:49:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5b5dc76c7ba492972d54bcbe8a8f5bd974b664e6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/zendframework/zend-cache/pulls/10/commits","review_comments_url":"https://api.github.com/repos/zendframework/zend-cache/pulls/10/comments","review_comment_url":"https://api.github.com/repos/zendframework/zend-cache/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zendframework/zend-cache/issues/10/comments","statuses_url":"https://api.github.com/repos/zendframework/zend-cache/statuses/3a7e5c1c84e1eb7834d0ac1b06850821c19d1760","head":{"label":"pensiero:feature/set-ttl-redis-adapter","ref":"feature/set-ttl-redis-adapter","sha":"3a7e5c1c84e1eb7834d0ac1b06850821c19d1760","user":{"login":"pensiero","id":2010696,"avatar_url":"https://avatars.githubusercontent.com/u/2010696?v=3","gravatar_id":"","url":"https://api.github.com/users/pensiero","html_url":"https://github.com/pensiero","followers_url":"https://api.github.com/users/pensiero/followers","following_url":"https://api.github.com/users/pensiero/following{/other_user}","gists_url":"https://api.github.com/users/pensiero/gists{/gist_id}","starred_url":"https://api.github.com/users/pensiero/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pensiero/subscriptions","organizations_url":"https://api.github.com/users/pensiero/orgs","repos_url":"https://api.github.com/users/pensiero/repos","events_url":"https://api.github.com/users/pensiero/events{/privacy}","received_events_url":"https://api.github.com/users/pensiero/received_events","type":"User","site_admin":false},"repo":{"id":37381135,"name":"zend-cache","full_name":"pensiero/zend-cache","owner":{"login":"pensiero","id":2010696,"avatar_url":"https://avatars.githubusercontent.com/u/2010696?v=3","gravatar_id":"","url":"https://api.github.com/users/pensiero","html_url":"https://github.com/pensiero","followers_url":"https://api.github.com/users/pensiero/followers","following_url":"https://api.github.com/users/pensiero/following{/other_user}","gists_url":"https://api.github.com/users/pensiero/gists{/gist_id}","starred_url":"https://api.github.com/users/pensiero/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pensiero/subscriptions","organizations_url":"https://api.github.com/users/pensiero/orgs","repos_url":"https://api.github.com/users/pensiero/repos","events_url":"https://api.github.com/users/pensiero/events{/privacy}","received_events_url":"https://api.github.com/users/pensiero/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pensiero/zend-cache","description":"","fork":true,"url":"https://api.github.com/repos/pensiero/zend-cache","forks_url":"https://api.github.com/repos/pensiero/zend-cache/forks","keys_url":"https://api.github.com/repos/pensiero/zend-cache/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pensiero/zend-cache/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pensiero/zend-cache/teams","hooks_url":"https://api.github.com/repos/pensiero/zend-cache/hooks","issue_events_url":"https://api.github.com/repos/pensiero/zend-cache/issues/events{/number}","events_url":"https://api.github.com/repos/pensiero/zend-cache/events","assignees_url":"https://api.github.com/repos/pensiero/zend-cache/assignees{/user}","branches_url":"https://api.github.com/repos/pensiero/zend-cache/branches{/branch}","tags_url":"https://api.github.com/repos/pensiero/zend-cache/tags","blobs_url":"https://api.github.com/repos/pensiero/zend-cache/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pensiero/zend-cache/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pensiero/zend-cache/git/refs{/sha}","trees_url":"https://api.github.com/repos/pensiero/zend-cache/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pensiero/zend-cache/statuses/{sha}","languages_url":"https://api.github.com/repos/pensiero/zend-cache/languages","stargazers_url":"https://api.github.com/repos/pensiero/zend-cache/stargazers","contributors_url":"https://api.github.com/repos/pensiero/zend-cache/contributors","subscribers_url":"https://api.github.com/repos/pensiero/zend-cache/subscribers","subscription_url":"https://api.github.com/repos/pensiero/zend-cache/subscription","commits_url":"https://api.github.com/repos/pensiero/zend-cache/commits{/sha}","git_commits_url":"https://api.github.com/repos/pensiero/zend-cache/git/commits{/sha}","comments_url":"https://api.github.com/repos/pensiero/zend-cache/comments{/number}","issue_comment_url":"https://api.github.com/repos/pensiero/zend-cache/issues/comments{/number}","contents_url":"https://api.github.com/repos/pensiero/zend-cache/contents/{+path}","compare_url":"https://api.github.com/repos/pensiero/zend-cache/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pensiero/zend-cache/merges","archive_url":"https://api.github.com/repos/pensiero/zend-cache/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pensiero/zend-cache/downloads","issues_url":"https://api.github.com/repos/pensiero/zend-cache/issues{/number}","pulls_url":"https://api.github.com/repos/pensiero/zend-cache/pulls{/number}","milestones_url":"https://api.github.com/repos/pensiero/zend-cache/milestones{/number}","notifications_url":"https://api.github.com/repos/pensiero/zend-cache/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pensiero/zend-cache/labels{/name}","releases_url":"https://api.github.com/repos/pensiero/zend-cache/releases{/id}","created_at":"2015-06-13T17:31:40Z","updated_at":"2015-06-13T17:31:41Z","pushed_at":"2015-06-14T11:25:09Z","git_url":"git://github.com/pensiero/zend-cache.git","ssh_url":"git@github.com:pensiero/zend-cache.git","clone_url":"https://github.com/pensiero/zend-cache.git","svn_url":"https://github.com/pensiero/zend-cache","homepage":null,"size":4280,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"zendframework:master","ref":"master","sha":"cc86ceb9e85c28c998abdc66e849c06d22672380","user":{"login":"zendframework","id":296074,"avatar_url":"https://avatars.githubusercontent.com/u/296074?v=3","gravatar_id":"","url":"https://api.github.com/users/zendframework","html_url":"https://github.com/zendframework","followers_url":"https://api.github.com/users/zendframework/followers","following_url":"https://api.github.com/users/zendframework/following{/other_user}","gists_url":"https://api.github.com/users/zendframework/gists{/gist_id}","starred_url":"https://api.github.com/users/zendframework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendframework/subscriptions","organizations_url":"https://api.github.com/users/zendframework/orgs","repos_url":"https://api.github.com/users/zendframework/repos","events_url":"https://api.github.com/users/zendframework/events{/privacy}","received_events_url":"https://api.github.com/users/zendframework/received_events","type":"Organization","site_admin":false},"repo":{"id":35625790,"name":"zend-cache","full_name":"zendframework/zend-cache","owner":{"login":"zendframework","id":296074,"avatar_url":"https://avatars.githubusercontent.com/u/296074?v=3","gravatar_id":"","url":"https://api.github.com/users/zendframework","html_url":"https://github.com/zendframework","followers_url":"https://api.github.com/users/zendframework/followers","following_url":"https://api.github.com/users/zendframework/following{/other_user}","gists_url":"https://api.github.com/users/zendframework/gists{/gist_id}","starred_url":"https://api.github.com/users/zendframework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zendframework/subscriptions","organizations_url":"https://api.github.com/users/zendframework/orgs","repos_url":"https://api.github.com/users/zendframework/repos","events_url":"https://api.github.com/users/zendframework/events{/privacy}","received_events_url":"https://api.github.com/users/zendframework/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zendframework/zend-cache","description":"","fork":false,"url":"https://api.github.com/repos/zendframework/zend-cache","forks_url":"https://api.github.com/repos/zendframework/zend-cache/forks","keys_url":"https://api.github.com/repos/zendframework/zend-cache/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zendframework/zend-cache/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zendframework/zend-cache/teams","hooks_url":"https://api.github.com/repos/zendframework/zend-cache/hooks","issue_events_url":"https://api.github.com/repos/zendframework/zend-cache/issues/events{/number}","events_url":"https://api.github.com/repos/zendframework/zend-cache/events","assignees_url":"https://api.github.com/repos/zendframework/zend-cache/assignees{/user}","branches_url":"https://api.github.com/repos/zendframework/zend-cache/branches{/branch}","tags_url":"https://api.github.com/repos/zendframework/zend-cache/tags","blobs_url":"https://api.github.com/repos/zendframework/zend-cache/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zendframework/zend-cache/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zendframework/zend-cache/git/refs{/sha}","trees_url":"https://api.github.com/repos/zendframework/zend-cache/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zendframework/zend-cache/statuses/{sha}","languages_url":"https://api.github.com/repos/zendframework/zend-cache/languages","stargazers_url":"https://api.github.com/repos/zendframework/zend-cache/stargazers","contributors_url":"https://api.github.com/repos/zendframework/zend-cache/contributors","subscribers_url":"https://api.github.com/repos/zendframework/zend-cache/subscribers","subscription_url":"https://api.github.com/repos/zendframework/zend-cache/subscription","commits_url":"https://api.github.com/repos/zendframework/zend-cache/commits{/sha}","git_commits_url":"https://api.github.com/repos/zendframework/zend-cache/git/commits{/sha}","comments_url":"https://api.github.com/repos/zendframework/zend-cache/comments{/number}","issue_comment_url":"https://api.github.com/repos/zendframework/zend-cache/issues/comments{/number}","contents_url":"https://api.github.com/repos/zendframework/zend-cache/contents/{+path}","compare_url":"https://api.github.com/repos/zendframework/zend-cache/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zendframework/zend-cache/merges","archive_url":"https://api.github.com/repos/zendframework/zend-cache/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zendframework/zend-cache/downloads","issues_url":"https://api.github.com/repos/zendframework/zend-cache/issues{/number}","pulls_url":"https://api.github.com/repos/zendframework/zend-cache/pulls{/number}","milestones_url":"https://api.github.com/repos/zendframework/zend-cache/milestones{/number}","notifications_url":"https://api.github.com/repos/zendframework/zend-cache/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zendframework/zend-cache/labels{/name}","releases_url":"https://api.github.com/repos/zendframework/zend-cache/releases{/id}","created_at":"2015-05-14T17:33:22Z","updated_at":"2015-06-03T23:30:00Z","pushed_at":"2015-06-14T11:25:10Z","git_url":"git://github.com/zendframework/zend-cache.git","ssh_url":"git@github.com:zendframework/zend-cache.git","clone_url":"https://github.com/zendframework/zend-cache.git","svn_url":"https://github.com/zendframework/zend-cache","homepage":null,"size":4280,"stargazers_count":3,"watchers_count":3,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"open_issues_count":7,"forks":6,"open_issues":7,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zendframework/zend-cache/pulls/10"},"html":{"href":"https://github.com/zendframework/zend-cache/pull/10"},"issue":{"href":"https://api.github.com/repos/zendframework/zend-cache/issues/10"},"comments":{"href":"https://api.github.com/repos/zendframework/zend-cache/issues/10/comments"},"review_comments":{"href":"https://api.github.com/repos/zendframework/zend-cache/pulls/10/comments"},"review_comment":{"href":"https://api.github.com/repos/zendframework/zend-cache/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zendframework/zend-cache/pulls/10/commits"},"statuses":{"href":"https://api.github.com/repos/zendframework/zend-cache/statuses/3a7e5c1c84e1eb7834d0ac1b06850821c19d1760"}}}}