Fixed Resources being unable to serve static files when using more complicated URI's.

This commit is contained in:
Abel Hoogeveen 2020-08-02 11:12:51 +02:00
parent e3485fa256
commit d7b2c40c57
Signed by: abelhooge
GPG Key ID: 387E8DC1F73306FC
3 changed files with 31 additions and 31 deletions

View File

@ -47,17 +47,17 @@ class ResourceServeEvent extends Event
/** /**
* @var array * @var array
*/ */
public $resourceUrlSegments; public $requestURL;
/** /**
* @var string * @var string
*/ */
public $resourceFilePath; public $resourceFilePath;
public function init(string $resourceName, array $resourceUrlSegments, string $resourceFilePath) public function init(string $resourceName, string $requestURL, string $resourceFilePath)
{ {
$this->resourceName = $resourceName; $this->resourceName = $resourceName;
$this->resourceUrlSegments = $resourceUrlSegments; $this->requestURL = $requestURL;
$this->resourceFilePath = $resourceFilePath; $this->resourceFilePath = $resourceFilePath;
} }
} }

View File

@ -61,10 +61,10 @@ class Resources
$this->output = Factory::getInstance()->output; $this->output = Factory::getInstance()->output;
} }
public function resourceExists(array $resourceUrlSegments): bool public function resourceExists(string $requestURL): bool
{ {
// First find the resource // First find the resource
$file = $this->findResource($resourceUrlSegments); $file = $this->findResource($requestURL);
// If not found, return false; // If not found, return false;
if (is_null($file)) if (is_null($file))
@ -77,17 +77,17 @@ class Resources
/** /**
* Serves a static file if found. * Serves a static file if found.
* *
* @param array $resourceUrlSegments * @param string $requestURL
* @return bool * @return bool
* @throws WebException * @throws WebException
* *
* @todo Bypass the Output system and use the readFile() method. * @todo Bypass the Output system and use the readFile() method.
* @todo Run as FuzeWorks pre-code, before creating the container * @todo Run as FuzeWorks pre-code, before creating the container
*/ */
public function serveResource(array $resourceUrlSegments): bool public function serveResource(string $requestURL): bool
{ {
// First find the resource // First find the resource
$file = $this->findResource($resourceUrlSegments); $file = $this->findResource($requestURL);
// If not found return false // If not found return false
if (is_null($file)) if (is_null($file))
@ -96,7 +96,7 @@ class Resources
// If a file is found, fire a serveResourceEvent // If a file is found, fire a serveResourceEvent
/** @var ResourceServeEvent $event */ /** @var ResourceServeEvent $event */
try { try {
$event = Events::fireEvent('resourceServeEvent', $file['resourceName'], $file['segments'], $file['file']); $event = Events::fireEvent('resourceServeEvent', $file['resourceName'], $file['requestURL'], $file['file']);
} catch (Exception\EventException $e) { } catch (Exception\EventException $e) {
throw new WebException("Could not serve resource. resourceServeEvent threw exception: '" . $e->getMessage() . "'"); throw new WebException("Could not serve resource. resourceServeEvent threw exception: '" . $e->getMessage() . "'");
} }
@ -106,7 +106,7 @@ class Resources
return false; return false;
// Log the resource serving // Log the resource serving
Logger::log("Serving static resource '/" . $file['resourceName'] . '/' . implode('/', $file['segments']) . "'"); Logger::log("Serving static resource '/" . $file['resourceName'] . '/' . $file['requestURL'] . "'");
// Serve file in accordance with event // Serve file in accordance with event
$fileExtension = pathinfo($event->resourceFilePath, PATHINFO_EXTENSION); $fileExtension = pathinfo($event->resourceFilePath, PATHINFO_EXTENSION);
@ -118,25 +118,22 @@ class Resources
return true; return true;
} }
protected function findResource(array $resourceUrlSegments): ?array protected function findResource(string $requestURL): ?array
{ {
// If too few segments provided, don't even bother
if (count($resourceUrlSegments) < 2)
return null;
// First segment should be the resourceName, check if it exists // First segment should be the resourceName, check if it exists
$resourceName = urldecode($resourceUrlSegments[1]); foreach ($this->resources as $resourceName => $resourceDir)
if (!isset($this->resources[$resourceName])) {
return null; if (substr($requestURL, 0, strlen($resourceName)) === $resourceName)
{
$fileURL = ltrim(substr($requestURL, strlen($resourceName)), '/');
$fileURL = str_replace('/', DS, $fileURL);
$file = $this->resources[$resourceName] . DS . $fileURL;
// If resource is found, generate file path // Test if file exists, if it does, return the string
$resourceUrlSegmentsBck = $resourceUrlSegments; if (file_exists($file) && is_file($file))
array_shift($resourceUrlSegments); return ['file' => $file, 'resourceName' => $resourceName, 'requestURL' => $fileURL];
$file = $this->resources[$resourceName] . DS . implode(DS, $resourceUrlSegments); }
}
// Test if file exists, if it does, return the string
if (file_exists($file) && is_file($file))
return ['file' => $file, 'resourceName' => $resourceName, 'segments' => $resourceUrlSegments];
return null; return null;
} }

View File

@ -242,7 +242,7 @@ class WebComponent implements iComponent
return true; return true;
// Attempt to load a static resource // Attempt to load a static resource
if ($resources->serveResource($uri->segmentArray())) if ($resources->serveResource($uri->uriString()))
return true; return true;
// First test for Cross Site Request Forgery // First test for Cross Site Request Forgery
@ -343,14 +343,17 @@ class WebComponent implements iComponent
/** @var Layout $layout */ /** @var Layout $layout */
$output = Factory::getInstance()->output; $output = Factory::getInstance()->output;
$router = Factory::getInstance()->router; $router = Factory::getInstance()->router;
$layout = Factory::getInstance()->layouts;
// Reset the layout engine
if (isset(Factory::getInstance()->layouts))
{
$layout = Factory::getInstance()->layouts;
$layout->reset();
}
// Cancel event // Cancel event
$event->setCancelled(true); $event->setCancelled(true);
// Reset the layout engine
$layout->reset();
// Remove listener so that error pages won't be intercepted // Remove listener so that error pages won't be intercepted
Events::removeListener([$this, 'callViewEventListener'], 'routerCallViewEvent',Priority::HIGHEST); Events::removeListener([$this, 'callViewEventListener'], 'routerCallViewEvent',Priority::HIGHEST);