From ceedd464fc84c724a51789eb9b7a5e0f1f5674e9 Mon Sep 17 00:00:00 2001 From: Thomas Alrek Date: Wed, 12 Jun 2019 13:20:28 +0200 Subject: [PATCH 1/4] Rewrite to use $_REQUEST instead of checking $_GET and $_POST individually --- src/Netflex/Site/Support/CaptchaV2.php | 13 ++++++++----- .../TestSuites/CaptchaV2/CaptchaV2.isValid.test.php | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Netflex/Site/Support/CaptchaV2.php b/src/Netflex/Site/Support/CaptchaV2.php index a37d396..30bc503 100644 --- a/src/Netflex/Site/Support/CaptchaV2.php +++ b/src/Netflex/Site/Support/CaptchaV2.php @@ -62,12 +62,15 @@ public static function checkBox() */ public static function isValid() { - if (array_key_exists('g-recaptcha-response', $_GET)) - $response = $_GET['g-recaptcha-response']; - if (array_key_exists('g-recaptcha-response', $_POST)) - $response = $_POST['g-recaptcha-response'];; - if (!isset($response)) + $response = null; + + if (array_key_exists('g-recaptcha-response', $_REQUEST)) { + $response = $_REQUEST['g-recaptcha-response']; + } + + if (is_null($response)) { throw new ResponseMissingException('g-recaptcha-response is missing from $_GET and $_POST'); + } $response = json_decode(NF::$capi->post('https://www.google.com/recaptcha/api/siteverify', [ 'form_params' => [ diff --git a/tests/TestSuites/CaptchaV2/CaptchaV2.isValid.test.php b/tests/TestSuites/CaptchaV2/CaptchaV2.isValid.test.php index 952bbb5..b195e55 100644 --- a/tests/TestSuites/CaptchaV2/CaptchaV2.isValid.test.php +++ b/tests/TestSuites/CaptchaV2/CaptchaV2.isValid.test.php @@ -24,7 +24,7 @@ public function testThrowsExceptionWhenParametersMissing (): void { } public function testHandlesRequestException (): void { - $_GET['g-recaptcha-response'] = 'test'; + $_REQUEST['g-recaptcha-response'] = 'test'; NF::$capi->mockResponse(new Response(500)); NF::$site->mockVariable('captcha_site_key', 'aabbccddeeff'); NF::$site->mockVariable('captcha_site_secret', '112233445566'); @@ -33,7 +33,7 @@ public function testHandlesRequestException (): void { } public function testHandlesValidCase (): void { - $_GET['g-recaptcha-response'] = 'test'; + $_REQUEST['g-recaptcha-response'] = 'test'; NF::$site->mockVariable('captcha_site_key', 'aabbccddeeff'); NF::$site->mockVariable('captcha_site_secret', '112233445566'); NF::$capi->mockResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode([ @@ -48,7 +48,7 @@ public function testHandlesValidCase (): void { } public function testHandlesInvalidCase (): void { - $_GET['g-recaptcha-response'] = 'test'; + $_REQUEST['g-recaptcha-response'] = 'test'; NF::$site->mockVariable('captcha_site_key', 'aabbccddeeff'); NF::$site->mockVariable('captcha_site_secret', '112233445566'); NF::$capi->mockResponse(new Response(200, ['Content-Type' => 'application/json'], json_encode([ From 8eea883ec20171902ab4af4905bbb782c2871bfe Mon Sep 17 00:00:00 2001 From: Tommy Stigen Olsen Date: Mon, 17 Jun 2019 13:11:56 +0200 Subject: [PATCH 2/4] =?UTF-8?q?Add=20one=20=E2=80=9Cget=20or=20set?= =?UTF-8?q?=E2=80=9D=20function=20using=20callbacks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Netflex/Site/Cache.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Netflex/Site/Cache.php b/src/Netflex/Site/Cache.php index 1bc07d5..a56cbeb 100644 --- a/src/Netflex/Site/Cache.php +++ b/src/Netflex/Site/Cache.php @@ -110,4 +110,33 @@ public function purge() { self::$cache->clear(); } + /** + * One line fetch or set cache function + * + * @param $key string Name of the cache key + * @param $ttl int Cache time to live + * @param $callback function A function that resolves the value if it is not already cached + */ + + public static function resolve($key, $ttl = 3600, $callback) { + if(self::$cache->has($key)) { + return self::$cache->get($key); + } else { + $ttlValue = NULL; + $ttlFunction = function(int $value) use (&$ttlValue) { + $ttlValue = $value; + }; + $args = (new \ReflectionFunction($callback))->getNumberOfParameters(); + if($args == 1) { + $response = $callback($ttlFunction); + $ttlValue = is_int($ttlValue) ? max(1, $ttlValue) : NULL; + nf::debug($ttlValue, "Cache->resolve($key) dynamic duration"); + } else { + $response = $callback(); + } + self::$cache->set($key, $response, "_", $ttlValue ?? $ttl); + return self::$cache->get($key); + } + } +} } From 957f6985325bbd707b2f4cd02a2dc87035b4666b Mon Sep 17 00:00:00 2001 From: Thomas Alrek Date: Mon, 17 Jun 2019 13:09:49 +0200 Subject: [PATCH 3/4] Refactor Console --- src/NF.php | 26 +++++++-------- src/Netflex/Site/Console.php | 61 ++++++++++++++++++++++++++++++++++++ tests/mocks/NF.php | 2 -- tests/mocks/PHPConsole.php | 7 ----- 4 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 src/Netflex/Site/Console.php delete mode 100644 tests/mocks/PHPConsole.php diff --git a/src/NF.php b/src/NF.php index 6ac5f4c..9d46fe8 100644 --- a/src/NF.php +++ b/src/NF.php @@ -9,7 +9,7 @@ use Netflex\Site\Commerce; use Netflex\Site\Search; use Netflex\Site\JWT; -use PhpConsole\Handler; +use Netflex\Site\Console; class NF { @@ -35,7 +35,10 @@ class NF public static $config; /** @var array[string]string */ public static $routes; - /** @var Handler */ + /** + * @deprecated 1.0.11 + * @var Console + * */ public static $console; /** @var string */ public static $sitename; @@ -83,7 +86,7 @@ public static function init($site = null, $branch = null, $path = []) self::clearCache(); } - self::$console = self::startPhpConsole(); + self::$console = Console::getInstance(); self::$site = new Site(); // Datastore for Netflex @@ -165,17 +168,13 @@ public static function nfPath($file) /** * Instantiates a PHPConsole session * - * @return PhpConsole + * @deprecated 1.0.11 + * @return Console */ public static function startPhpConsole() { - $console = null; - if (getenv('ENV') !== 'master') { - $console = Handler::getInstance(); - $console->getConnector()->setSourcesBasePath($_SERVER['DOCUMENT_ROOT']); - $console->start(); - } - return $console; + trigger_error('NF::startPhpConsole is deprecated', E_USER_DEPRECATED); + return new Console(); } /** @@ -186,9 +185,8 @@ public static function startPhpConsole() */ public static function debug($text, $label = null) { - if (self::$console) { - self::$console->debug($text, $label); - } + $console = Console::getInstance(); + $console->log($text, $label); } /** diff --git a/src/Netflex/Site/Console.php b/src/Netflex/Site/Console.php new file mode 100644 index 0000000..3cc633b --- /dev/null +++ b/src/Netflex/Site/Console.php @@ -0,0 +1,61 @@ +handler = Handler::getInstance();; + $this->handler->getConnector()->setSourcesBasePath($_SERVER['DOCUMENT_ROOT']); + $this->handler->start(); + } + } + + /** + * Instantiates a Console instance + * + * @return Console + */ + public static function getInstance () { + if (!self::$instance) { + self::$instance = new static; + } + + return self::$instance; + } + + /** + * Logs the text to console (if not in production) + * + * @param string $text + * @param string $labels One or more labels separated by . + * @return void + */ + public function log ($text, $labels = null) { + if ($this->handler) { + $this->handler->debug($text, $labels); + } + } + + /** + * @deprecated 1.0.11 + * + * @param string $text + * @param string $label + * @return void + */ + public function debug ($text, $label) + { + trigger_error('NF::$console->debug is deprecated', E_USER_DEPRECATED); + return $this->log($text, $label); + } +} diff --git a/tests/mocks/NF.php b/tests/mocks/NF.php index 326afd0..af8dcca 100644 --- a/tests/mocks/NF.php +++ b/tests/mocks/NF.php @@ -3,10 +3,8 @@ require_once(__DIR__ . '/Cache.php'); require_once(__DIR__ . '/Guzzle.php'); require_once(__DIR__ . '/Site.php'); -require_once(__DIR__ . '/PHPConsole.php'); NF::$capi = new MockGuzzle(); NF::$cache = new MockCache(); NF::$site = new MockSite(); -NF::$console = new MockPHPConsole(); NF::$site_root = __DIR__ . '/project/'; diff --git a/tests/mocks/PHPConsole.php b/tests/mocks/PHPConsole.php deleted file mode 100644 index 9bec15f..0000000 --- a/tests/mocks/PHPConsole.php +++ /dev/null @@ -1,7 +0,0 @@ - Date: Mon, 17 Jun 2019 14:11:26 +0200 Subject: [PATCH 4/4] Add docblocks to cache methods --- src/Netflex/Site/Cache.php | 133 +++++++++++++++++++++++++++++-------- 1 file changed, 107 insertions(+), 26 deletions(-) diff --git a/src/Netflex/Site/Cache.php b/src/Netflex/Site/Cache.php index a56cbeb..a5b9176 100644 --- a/src/Netflex/Site/Cache.php +++ b/src/Netflex/Site/Cache.php @@ -3,6 +3,7 @@ use NF; use Exception; +use ReflectionFunction; use Phpfastcache\CacheManager; use Phpfastcache\Drivers\Files\Config as FilesConfig; use Phpfastcache\Drivers\Memcached\Config as MemcachedConfig; @@ -10,12 +11,13 @@ class Cache { + /** @var string */ + private static $key; - private static $key; + /** @var \Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface */ private static $cache; public function __construct() { - self::$key = NF::$sitename; $config = null; @@ -23,21 +25,24 @@ public function __construct() { switch ($driver) { case 'memcached': - $memcached_hostname = getenv("MEMCACHED_HOST") ? getenv("MEMCACHED_HOST") : '127.0.0.1'; - $memcached_port = getenv("MEMCACHED_PORT") ? intval(getenv("MEMCACHED_PORT")) : 11211; + $memcached_hostname = getenv('MEMCACHED_HOST') ? getenv('MEMCACHED_HOST') : '127.0.0.1'; + $memcached_port = getenv('MEMCACHED_PORT') ? intval(getenv('MEMCACHED_PORT')) : 11211; $config = new MemcachedConfig([ 'host' => $memcached_hostname, 'port' => $memcached_port, ]); + break; case 'files': if (!file_exists(NF::$cacheDir . 'cache/')) { mkdir(NF::$cacheDir. 'cache/', 0755, true); } + $config = new FilesConfig([ 'path' => NF::$cacheDir . 'cache/' ]); + break; default: throw new Exception('Invalid Cache driver'); @@ -46,68 +51,142 @@ public function __construct() { self::$cache = CacheManager::getInstance($driver, $config); } + /** + * Creates a prefixed cache key + * + * @param string $key + * @return string + */ public function getCacheKey($key) { return md5(self::$key . $key); } + /** + * This function is only an alias for fetch. + * + * @see fetch + * @param string $key + * @return mixed + */ public function get ($key) { return $this->fetch($key); } /** * This function is only an alias for save. + * * @see save - * @return void + * @return bool */ public function set($key, $value, $_=false, $ttl) { return $this->save($key, $value, $ttl, null); } + /** + * This function is only an alias for save. + * + * @see save + * @return bool + */ public function add ($key, $value, $_ = false, $ttl) { return $this->save($key, $value, $ttl, null); } + /** + * Fetches item from cache by $key + * + * @param string $key + * @return mixed + */ public function fetch($key) { $item = self::$cache->getItem(self::getCacheKey($key)); $item = unserialize($item->get()); return $item; } + /** + * Checks is $key exists in the cache + * + * @param string $key + * @return bool + */ public function has($key) { $item = self::$cache->getItem(self::getCacheKey($key)); return !is_null($item->get()); } + /** + * Stores an item in the cache + * + * @param string $key + * @param mixed $value + * @param int $ttl = 0 + * @param string $tag = null + * @return bool + */ public function save($key, $value, $ttl = 0, $tag = null) { $value = serialize($value); $item = self::$cache->getItem(self::getCacheKey($key)); $item->set($value)->expiresAfter($ttl); - self::$cache->save($item); + return self::$cache->save($item); } + /** + * Stores an array of items in the cache + * + * @param array $items + * @return void + */ public function saveMultiple(array $items) { foreach($items as $item) { $this->save($item['key'], $item['value'], $item['ttl'], $item['tag']); } } + /** + * Deletes the item from the cache + * + * @param string $key + * @return bool + */ public function delete($key) { $key = self::getCacheKey($key); - self::$cache->deleteItem($key); + return self::$cache->deleteItem($key); } + /** + * Deletes an array of items from the cache + * + * @param array $keys + * @return void + */ public function deleteMultiple(array $keys) { foreach($keys as $key) { $this->delete($key); } } + /** + * Deletes items by tag + * + * @param string|array $tag + * @return bool + */ public function deleteTag($tag) { - self::$cache->deleteItemsByTags($tags); + if (is_array($tag)) { + return self::$cache->deleteItemsByTags($tag); + } + + return self::$cache->deleteItemsByTag($tag); } + /** + * Purges all items from the cache + * + * @return bool + */ public function purge() { - self::$cache->clear(); + return self::$cache->clear(); } /** @@ -117,26 +196,28 @@ public function purge() { * @param $ttl int Cache time to live * @param $callback function A function that resolves the value if it is not already cached */ - public static function resolve($key, $ttl = 3600, $callback) { - if(self::$cache->has($key)) { + if (self::$cache->has($key)) { return self::$cache->get($key); + } + + $ttlValue = null; + $ttlFunction = function(int $value) use (&$ttlValue) { + $ttlValue = $value; + }; + + $args = (new ReflectionFunction($callback))->getNumberOfParameters(); + + if ($args == 1) { + $response = $callback($ttlFunction); + $ttlValue = is_int($ttlValue) ? max(1, $ttlValue) : NULL; + NF::debug($ttlValue, 'Cache->resolve(' . $key . ') dynamic duration'); } else { - $ttlValue = NULL; - $ttlFunction = function(int $value) use (&$ttlValue) { - $ttlValue = $value; - }; - $args = (new \ReflectionFunction($callback))->getNumberOfParameters(); - if($args == 1) { - $response = $callback($ttlFunction); - $ttlValue = is_int($ttlValue) ? max(1, $ttlValue) : NULL; - nf::debug($ttlValue, "Cache->resolve($key) dynamic duration"); - } else { - $response = $callback(); - } - self::$cache->set($key, $response, "_", $ttlValue ?? $ttl); - return self::$cache->get($key); + $response = $callback(); } + + self::$cache->set($key, $response, '_', $ttlValue ?? $ttl); + + return self::$cache->get($key); } } -}