Skip to content

Commit e0f76b2

Browse files
committed
Dispatch Components
1 parent 47ad46a commit e0f76b2

File tree

11 files changed

+185
-1
lines changed

11 files changed

+185
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
namespace Packaged\Dispatch\Component;
3+
4+
interface DispatchableComponent
5+
{
6+
public function getResourceDirectory();
7+
}

src/Dispatch.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace Packaged\Dispatch;
33

4+
use Packaged\Dispatch\Component\DispatchableComponent;
45
use Packaged\Dispatch\Resources\AbstractDispatchableResource;
56
use Packaged\Dispatch\Resources\AbstractResource;
67
use Packaged\Dispatch\Resources\DispatchableResource;
@@ -45,6 +46,7 @@ public static function destroy()
4546

4647
protected $_aliases = [];
4748
protected $_projectRoot;
49+
protected $_componentsNamespace;
4850

4951
public function __construct($projectRoot, $baseUri = null)
5052
{
@@ -84,6 +86,25 @@ public function getBaseUri()
8486
return $this->_baseUri;
8587
}
8688

89+
/**
90+
* @return mixed
91+
*/
92+
public function getComponentsNamespace()
93+
{
94+
return $this->_componentsNamespace;
95+
}
96+
97+
/**
98+
* @param mixed $componentsNs
99+
*
100+
* @return Dispatch
101+
*/
102+
public function setComponentsNamespace($componentsNs)
103+
{
104+
$this->_componentsNamespace = $componentsNs;
105+
return $this;
106+
}
107+
87108
/**
88109
* @param Request $request
89110
*
@@ -109,6 +130,34 @@ public function handle(Request $request): Response
109130
case ResourceManager::MAP_PUBLIC:
110131
$manager = ResourceManager::public();
111132
break;
133+
case ResourceManager::MAP_COMPONENT:
134+
$len = array_shift($pathParts);
135+
$class = '';
136+
for($i = 0; $i < $len; $i++)
137+
{
138+
$part = array_shift($pathParts);
139+
if($i == 0 && $part == '_')
140+
{
141+
$class = $this->getComponentsNamespace();
142+
}
143+
else
144+
{
145+
$class .= '\\' . $part;
146+
}
147+
}
148+
if(class_exists($class))
149+
{
150+
$component = new $class();
151+
if($component instanceof DispatchableComponent)
152+
{
153+
$manager = ResourceManager::component($component);
154+
}
155+
}
156+
if(!isset($manager))
157+
{
158+
return Response::create("Component Not Found", 404);
159+
}
160+
break;
112161
default:
113162
return Response::create("File Not Found", 404);
114163
}

src/ResourceManager.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace Packaged\Dispatch;
33

4+
use Packaged\Dispatch\Component\DispatchableComponent;
45
use Packaged\Helpers\Path;
56
use Packaged\Helpers\Strings;
67

@@ -11,10 +12,13 @@ class ResourceManager
1112
const MAP_ALIAS = 'a';
1213
const MAP_RESOURCES = 'r';
1314
const MAP_PUBLIC = 'p';
15+
const MAP_COMPONENT = 'c';
1416

1517
protected $_type = self::MAP_RESOURCES;
1618
protected $_mapOptions = [];
1719
protected $_baseUri = [];
20+
/** @var DispatchableComponent */
21+
protected $_component;
1822

1923
public function __construct($type, array $options = [])
2024
{
@@ -58,6 +62,22 @@ public static function inline()
5862
return new static(self::MAP_INLINE, []);
5963
}
6064

65+
public static function component(DispatchableComponent $component)
66+
{
67+
$dispatch = Dispatch::instance();
68+
$class = get_class($component);
69+
if($dispatch)
70+
{
71+
$prefix = Strings::commonPrefix($class, ltrim($dispatch->getComponentsNamespace(), '\\'));
72+
$class = str_replace($prefix, '_', $class);
73+
}
74+
$parts = explode('\\', $class);
75+
array_unshift($parts, count($parts));
76+
$manager = new static(self::MAP_COMPONENT, $parts);
77+
$manager->_component = $component;
78+
return $manager;
79+
}
80+
6181
/**
6282
* @param $relativeFullPath
6383
*
@@ -106,6 +126,10 @@ public function getFilePath($relativePath)
106126
{
107127
return Path::system(Dispatch::instance()->getAliasPath($this->_mapOptions[0]), $relativePath);
108128
}
129+
else if($this->_type == self::MAP_COMPONENT && $this->_component)
130+
{
131+
return Path::system($this->_component->getResourceDirectory(), $relativePath);
132+
}
109133
throw new \Exception("invalid map type");
110134
}
111135

@@ -131,7 +155,7 @@ public function getFileHash($fullPath)
131155

132156
if($hash && function_exists('apcu_store'))
133157
{
134-
apcu_store($key, $hash, 86400);
158+
$res = apcu_store($key, $hash, 86400);
135159
}
136160

137161
return $hash;

src/ResourceStore.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ class ResourceStore
1010

1111
protected $_store = [];
1212

13+
public function getResources($type = null)
14+
{
15+
return $this->_store[$type] ?? null;
16+
}
17+
1318
public function generateHtmlIncludes($for = self::TYPE_CSS)
1419
{
1520
if(!isset($this->_store[$for]) || empty($this->_store[$for]))

tests/DispatchTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use Packaged\Dispatch\Dispatch;
66
use Packaged\Dispatch\ResourceManager;
77
use Packaged\Dispatch\ResourceStore;
8+
use Packaged\Dispatch\Tests\TestComponents\DemoComponent\DemoComponent;
9+
use Packaged\Dispatch\Tests\TestComponents\DemoComponent\ResourcedDemoComponent;
810
use Packaged\Helpers\Path;
911
use Packaged\Http\Request;
1012
use PHPUnit\Framework\TestCase;
@@ -88,4 +90,33 @@ public function testStore()
8890
$this->assertContains('src="http://assets.packaged.in/r/ef6402a7/js/alert.js"', $response);
8991
Dispatch::destroy();
9092
}
93+
94+
public function testComponent()
95+
{
96+
$dispatch = new Dispatch(Path::system(__DIR__, '_root'));
97+
Dispatch::bind($dispatch);
98+
99+
$component = new DemoComponent();
100+
Dispatch::instance()->setComponentsNamespace('\Packaged\Dispatch\Tests\TestComponents');
101+
$manager = ResourceManager::component($component);
102+
$uri = $manager->getResourceUri('style.css');
103+
$this->assertEquals('c/3/_/DemoComponent/DemoComponent/a4197ed8/style.css', $uri);
104+
105+
$request = Request::create('/' . $uri);
106+
$response = $dispatch->handle($request);
107+
$this->assertEquals(200, $response->getStatusCode());
108+
$this->assertContains('body{color:red}', $response->getContent());
109+
110+
$resourceComponent = new ResourcedDemoComponent();
111+
$manager = ResourceManager::component($resourceComponent);
112+
$request = Request::create('/' . $manager->getResourceUri('style.css'));
113+
$response = $dispatch->handle($request);
114+
$this->assertEquals(200, $response->getStatusCode());
115+
$this->assertContains('body{color:orange}', $response->getContent());
116+
117+
$request = Request::create('/c/3/_/MissingComponent/DemoComponent/a4197ed8/style.css');
118+
$response = $dispatch->handle($request);
119+
$this->assertEquals(404, $response->getStatusCode());
120+
$this->assertContains('Component Not Found', $response->getContent());
121+
}
91122
}

tests/ResourceManagerTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Packaged\Dispatch\Dispatch;
66
use Packaged\Dispatch\ResourceManager;
77
use Packaged\Dispatch\ResourceStore;
8+
use Packaged\Dispatch\Tests\TestComponents\DemoComponent\DemoComponent;
89
use Packaged\Helpers\Path;
910
use PHPUnit\Framework\TestCase;
1011

@@ -39,6 +40,28 @@ public function testPublic()
3940
$this->assertEquals([], $manager->getMapOptions());
4041
}
4142

43+
public function testComponent()
44+
{
45+
Dispatch::bind(new Dispatch(Path::system(__DIR__, '_root')));
46+
$component = new DemoComponent();
47+
$manager = ResourceManager::component($component);
48+
$this->assertEquals(ResourceManager::MAP_COMPONENT, $manager->getMapType());
49+
$this->assertEquals(
50+
[6, 'Packaged', 'Dispatch', 'Tests', 'TestComponents', 'DemoComponent', 'DemoComponent'],
51+
$manager->getMapOptions()
52+
);
53+
$this->assertEquals(
54+
'c/6/Packaged/Dispatch/Tests/TestComponents/DemoComponent/DemoComponent/a4197ed8/style.css',
55+
$manager->getResourceUri('style.css')
56+
);
57+
Dispatch::instance()->setComponentsNamespace('\Packaged\Dispatch\Tests\TestComponents');
58+
$manager = ResourceManager::component($component);
59+
$this->assertEquals(
60+
'c/3/_/DemoComponent/DemoComponent/a4197ed8/style.css',
61+
$manager->getResourceUri('style.css')
62+
);
63+
}
64+
4265
public function testRequireJs()
4366
{
4467
Dispatch::bind(new Dispatch(Path::system(__DIR__, '_root')));
@@ -49,6 +72,17 @@ public function testRequireJs()
4972
);
5073
}
5174

75+
public function testUniqueRequire()
76+
{
77+
Dispatch::bind(new Dispatch(Path::system(__DIR__, '_root')));
78+
ResourceManager::resources()->requireJs('js/alert.js');
79+
$this->assertCount(1, Dispatch::instance()->store()->getResources(ResourceStore::TYPE_JS));
80+
ResourceManager::resources()->requireJs('js/alert.js');
81+
$this->assertCount(1, Dispatch::instance()->store()->getResources(ResourceStore::TYPE_JS));
82+
ResourceManager::resources()->requireJs('js/misc.js');
83+
$this->assertCount(2, Dispatch::instance()->store()->getResources(ResourceStore::TYPE_JS));
84+
}
85+
5286
public function testRequireCss()
5387
{
5488
Dispatch::bind(new Dispatch(Path::system(__DIR__, '_root')));
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
namespace Packaged\Dispatch\Tests\TestComponents\DemoComponent;
3+
4+
use Packaged\Dispatch\Component\DispatchableComponent;
5+
6+
class DemoComponent implements DispatchableComponent
7+
{
8+
public function getResourceDirectory()
9+
{
10+
return __DIR__;
11+
}
12+
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
namespace Packaged\Dispatch\Tests\TestComponents\DemoComponent;
3+
4+
use Packaged\Dispatch\Component\DispatchableComponent;
5+
use Packaged\Helpers\Path;
6+
7+
class ResourcedDemoComponent implements DispatchableComponent
8+
{
9+
public function getResourceDirectory()
10+
{
11+
return Path::system(__DIR__, 'resources');
12+
}
13+
14+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
color: orange;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
color: red;
3+
}

0 commit comments

Comments
 (0)