Skip to content

Commit

Permalink
Release 4.0.0-beta.4
Browse files Browse the repository at this point in the history
  • Loading branch information
jim-parry committed Jul 25, 2019
1 parent 4fc8c85 commit 8ee7a2a
Show file tree
Hide file tree
Showing 128 changed files with 3,277 additions and 289 deletions.
1 change: 0 additions & 1 deletion app/Controllers/Home.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php namespace App\Controllers;

use CodeIgniter\Controller;
use App\Models\UserModel;

class Home extends BaseController
Expand Down
56 changes: 30 additions & 26 deletions system/Autoloader/FileLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p
unset($segments[0]);
}

$path = '';
$paths = [];
$prefix = '';
$filename = '';

Expand All @@ -115,31 +115,46 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p

while (! empty($segments))
{
$prefix .= empty($prefix)
? ucfirst(array_shift($segments))
: '\\' . ucfirst(array_shift($segments));
$prefix .= empty($prefix) ? array_shift($segments) : '\\' . array_shift($segments);

if (empty($namespaces[$prefix]))
{
continue;
}
$path = $this->getNamespaces($prefix);
$paths = $namespaces[$prefix];

$filename = implode('/', $segments);
break;
}

// IF we have a folder name, then the calling function
// expects this file to be within that folder, like 'Views',
// or 'libraries'.
if (! empty($folder) && strpos($path . $filename, '/' . $folder . '/') === false)

// if no namespaces matched then quit
if (empty($paths))
{
$filename = $folder . '/' . $filename;
return false;
}

// Check each path in the namespace
foreach ($paths as $path)
{
// Ensure trailing slash
$path = rtrim($path, '/') . '/';

// If we have a folder name, then the calling function
// expects this file to be within that folder, like 'Views',
// or 'libraries'.
if (! empty($folder) && strpos($path . $filename, '/' . $folder . '/') === false)
{
$path .= trim($folder, '/') . '/';
}

$path .= $filename;

return is_file($path) ? $path : false;
$path .= $filename;
if (is_file($path))
{
return $path;
}
}

return false;
}

//--------------------------------------------------------------------
Expand Down Expand Up @@ -265,21 +280,10 @@ protected function ensureExt(string $path, string $ext): string
/**
* Return the namespace mappings we know about.
*
* @param string|null $prefix
*
* @return array|string
*/
protected function getNamespaces(string $prefix = null)
protected function getNamespaces()
{
if ($prefix)
{
$path = $this->autoloader->getNamespace($prefix);

return isset($path[0])
? rtrim($path[0], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR
: '';
}

$namespaces = [];

foreach ($this->autoloader->getNamespace() as $prefix => $paths)
Expand Down
16 changes: 15 additions & 1 deletion system/Cache/CacheFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
namespace CodeIgniter\Cache;

use CodeIgniter\Cache\Exceptions\CacheException;
use CodeIgniter\Exceptions\CriticalError;

/**
* Class Cache
Expand Down Expand Up @@ -93,7 +94,20 @@ public static function getHandler($config, string $handler = null, string $backu
}
}

$adapter->initialize();
// If $adapter->initialization throws a CriticalError exception, we will attempt to
// use the $backup handler, if that also fails, we resort to the dummy handler.
try
{
$adapter->initialize();
}
catch (CriticalError $e)
{
// log the fact that an exception occurred as well what handler we are resorting to
log_message('critical', $e->getMessage() . ' Resorting to using ' . $backup . ' handler.');

// get the next best cache handler (or dummy if the $backup also fails)
$adapter = self::getHandler($config, $backup, 'dummy');
}

return $adapter;
}
Expand Down
77 changes: 55 additions & 22 deletions system/Cache/Handlers/MemcachedHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,35 +115,68 @@ public function __destruct()
*/
public function initialize()
{
if (class_exists('\Memcached'))
// Try to connect to Memcache or Memcached, if an issue occurs throw a CriticalError exception,
// so that the CacheFactory can attempt to initiate the next cache handler.
try
{
$this->memcached = new \Memcached();
if ($this->config['raw'])
if (class_exists('\Memcached'))
{
$this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
// Create new instance of \Memcached
$this->memcached = new \Memcached();
if ($this->config['raw'])
{
$this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
}

// Add server
$this->memcached->addServer(
$this->config['host'], $this->config['port'], $this->config['weight']
);

// attempt to get status of servers
$stats = $this->memcached->getStats();

// $stats should be an associate array with a key in the format of host:port.
// If it doesn't have the key, we know the server is not working as expected.
if( !isset($stats[$this->config['host']. ':' .$this->config['port']]) )
{
throw new CriticalError('Cache: Memcached connection failed.');
}
}
}
elseif (class_exists('\Memcache'))
{
$this->memcached = new \Memcache();
}
else
{
throw new CriticalError('Cache: Not support Memcache(d) extension.');
}
elseif (class_exists('\Memcache'))
{
// Create new instance of \Memcache
$this->memcached = new \Memcache();

if ($this->memcached instanceof \Memcached)
// Check if we can connect to the server
$can_connect = $this->memcached->connect(
$this->config['host'], $this->config['port']
);

// If we can't connect, throw a CriticalError exception
if($can_connect == false){
throw new CriticalError('Cache: Memcache connection failed.');
}

// Add server, third parameter is persistence and defaults to TRUE.
$this->memcached->addServer(
$this->config['host'], $this->config['port'], true, $this->config['weight']
);
}
else
{
throw new CriticalError('Cache: Not support Memcache(d) extension.');
}
}
catch (CriticalError $e)
{
$this->memcached->addServer(
$this->config['host'], $this->config['port'], $this->config['weight']
);
// If a CriticalError exception occurs, throw it up.
throw $e;
}
elseif ($this->memcached instanceof \Memcache)
catch (\Exception $e)
{
// Third parameter is persistence and defaults to TRUE.
$this->memcached->addServer(
$this->config['host'], $this->config['port'], true, $this->config['weight']
);
// If an \Exception occurs, convert it into a CriticalError exception and throw it.
throw new CriticalError('Cache: Memcache(d) connection refused (' . $e->getMessage() . ').');
}
}

Expand Down
4 changes: 3 additions & 1 deletion system/Cache/Handlers/PredisHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public function __construct($config)
*/
public function initialize()
{
// Try to connect to Redis, if an issue occurs throw a CriticalError exception,
// so that the CacheFactory can attempt to initiate the next cache handler.
try
{
// Create a new instance of Predis\Client
Expand All @@ -110,7 +112,7 @@ public function initialize()
catch (\Exception $e)
{
// thrown if can't connect to redis server.
throw new CriticalError('Cache: Predis connection refused (' . $e->getMessage() . ')');
throw new CriticalError('Cache: Predis connection refused (' . $e->getMessage() . ').');
}
}

Expand Down
38 changes: 29 additions & 9 deletions system/Cache/Handlers/RedisHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
namespace CodeIgniter\Cache\Handlers;

use CodeIgniter\Cache\CacheInterface;
use CodeIgniter\Exceptions\CriticalError;

/**
* Redis cache handler
Expand Down Expand Up @@ -116,19 +117,38 @@ public function initialize()
$config = $this->config;

$this->redis = new \Redis();
if (! $this->redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout']))
{
log_message('error', 'Cache: Redis connection failed. Check your configuration.');
}

if (isset($config['password']) && ! $this->redis->auth($config['password']))
// Try to connect to Redis, if an issue occurs throw a CriticalError exception,
// so that the CacheFactory can attempt to initiate the next cache handler.
try
{
log_message('error', 'Cache: Redis authentication failed.');
// Note:: If Redis is your primary cache choice, and it is "offline", every page load will end up been delayed by the timeout duration.
// I feel like some sort of temporary flag should be set, to indicate that we think Redis is "offline", allowing us to bypass the timeout for a set period of time.

if (! $this->redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout']))
{
// Note:: I'm unsure if log_message() is necessary, however I'm not 100% comfortable removing it.
log_message('error', 'Cache: Redis connection failed. Check your configuration.');
throw new CriticalError('Cache: Redis connection failed. Check your configuration.');
}

if (isset($config['password']) && ! $this->redis->auth($config['password']))
{
log_message('error', 'Cache: Redis authentication failed.');
throw new CriticalError('Cache: Redis authentication failed.');
}

if (isset($config['database']) && ! $this->redis->select($config['database']))
{
log_message('error', 'Cache: Redis select database failed.');
throw new CriticalError('Cache: Redis select database failed.');
}
}

if (isset($config['database']) && ! $this->redis->select($config['database']))
catch (\RedisException $e)
{
log_message('error', 'Cache: Redis select database failed.');
// $this->redis->connect() can sometimes throw a RedisException.
// We need to convert the exception into a CriticalError exception and throw it.
throw new CriticalError('Cache: RedisException occurred with message (' . $e->getMessage() . ').');
}
}

Expand Down
13 changes: 3 additions & 10 deletions system/CodeIgniter.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class CodeIgniter
/**
* The current version of CodeIgniter Framework
*/
const CI_VERSION = '4.0.0-beta.3';
const CI_VERSION = '4.0.0-beta.4';

/**
* App startup time.
Expand Down Expand Up @@ -642,7 +642,7 @@ public function getPerformanceStats(): array
*/
protected function generateCacheName($config): string
{
if (is_cli() && ! (ENVIRONMENT === 'testing'))
if (get_class($this->request) === CLIRequest::class)
{
return md5($this->request->getPath());
}
Expand Down Expand Up @@ -704,7 +704,7 @@ protected function tryToRouteIt(RouteCollectionInterface $routes = null)
}

// $routes is defined in Config/Routes.php
$this->router = Services::router($routes);
$this->router = Services::router($routes, $this->request);

$path = $this->determinePath();

Expand Down Expand Up @@ -985,16 +985,9 @@ public function storePreviousURL($uri)
/**
* Modifies the Request Object to use a different method if a POST
* variable called _method is found.
*
* Does not work on CLI commands.
*/
public function spoofRequestMethod()
{
if (is_cli())
{
return;
}

// Only works with POSTED forms
if ($this->request->getMethod() !== 'post')
{
Expand Down
2 changes: 1 addition & 1 deletion system/Commands/Database/MigrateRollback.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public function run(array $params = [])
}
else
{
// Get all namespaces form PSR4 paths.
// Get all namespaces from PSR4 paths.
$config = new Autoload();
$namespaces = $config->psr4;
foreach ($namespaces as $namespace => $path)
Expand Down
1 change: 1 addition & 0 deletions system/Commands/Utilities/Routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public function run(array $params)
'get',
'head',
'post',
'patch',
'put',
'delete',
'options',
Expand Down
2 changes: 2 additions & 0 deletions system/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,8 @@ function force_https(int $duration = 31536000, RequestInterface $request = null,
// Set an HSTS header
$response->setHeader('Strict-Transport-Security', 'max-age=' . $duration);
$response->redirect($uri);
$response->sendHeaders();

exit();
}
}
Expand Down
21 changes: 18 additions & 3 deletions system/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,28 @@ private static function createClass(string $name)
{
return new $name();
}

$locator = Services::locator();
$file = $locator->locateFile($name, 'Config');

if (empty($file))
{
return null;
// No file found - check if the class was namespaced
if (strpos($name, '\\') !== false)
{
// Class was namespaced and locateFile couldn't find it
return null;
}

// Check all namespaces
$files = $locator->search('Config/' . $name);
if (empty($files))
{
return null;
}

// Get the first match (prioritizes user and framework)
$file = reset($files);
}

$name = $locator->getClassname($file);
Expand Down
Loading

0 comments on commit 8ee7a2a

Please sign in to comment.