Path: blob/master/src/applications/celerity/CelerityResourceMap.php
12249 views
<?php12/**3* Interface to the static resource map, which is a graph of available4* resources, resource dependencies, and packaging information. You generally do5* not need to invoke it directly; instead, you call higher-level Celerity APIs6* and it uses the resource map to satisfy your requests.7*/8final class CelerityResourceMap extends Phobject {910private static $instances = array();1112private $resources;13private $symbolMap;14private $requiresMap;15private $packageMap;16private $nameMap;17private $hashMap;18private $componentMap;1920public function __construct(CelerityResources $resources) {21$this->resources = $resources;2223$map = $resources->loadMap();24$this->symbolMap = idx($map, 'symbols', array());25$this->requiresMap = idx($map, 'requires', array());26$this->packageMap = idx($map, 'packages', array());27$this->nameMap = idx($map, 'names', array());2829// We derive these reverse maps at runtime.3031$this->hashMap = array_flip($this->nameMap);32$this->componentMap = array();33foreach ($this->packageMap as $package_name => $symbols) {34foreach ($symbols as $symbol) {35$this->componentMap[$symbol] = $package_name;36}37}38}3940public static function getNamedInstance($name) {41if (empty(self::$instances[$name])) {42$resources_list = CelerityPhysicalResources::getAll();43if (empty($resources_list[$name])) {44throw new Exception(45pht(46'No resource source exists with name "%s"!',47$name));48}4950$instance = new CelerityResourceMap($resources_list[$name]);51self::$instances[$name] = $instance;52}5354return self::$instances[$name];55}5657public function getNameMap() {58return $this->nameMap;59}6061public function getSymbolMap() {62return $this->symbolMap;63}6465public function getRequiresMap() {66return $this->requiresMap;67}6869public function getPackageMap() {70return $this->packageMap;71}7273public function getPackagedNamesForSymbols(array $symbols) {74$resolved = $this->resolveResources($symbols);75return $this->packageResources($resolved);76}7778private function resolveResources(array $symbols) {79$map = array();80foreach ($symbols as $symbol) {81if (!empty($map[$symbol])) {82continue;83}84$this->resolveResource($map, $symbol);85}8687return $map;88}8990private function resolveResource(array &$map, $symbol) {91if (empty($this->symbolMap[$symbol])) {92throw new Exception(93pht(94'Attempting to resolve unknown resource, "%s".',95$symbol));96}9798$hash = $this->symbolMap[$symbol];99100$map[$symbol] = $hash;101102if (isset($this->requiresMap[$hash])) {103$requires = $this->requiresMap[$hash];104} else {105$requires = array();106}107108foreach ($requires as $required_symbol) {109if (!empty($map[$required_symbol])) {110continue;111}112$this->resolveResource($map, $required_symbol);113}114}115116private function packageResources(array $resolved_map) {117$packaged = array();118$handled = array();119foreach ($resolved_map as $symbol => $hash) {120if (isset($handled[$symbol])) {121continue;122}123124if (empty($this->componentMap[$symbol])) {125$packaged[] = $this->hashMap[$hash];126} else {127$package_name = $this->componentMap[$symbol];128$packaged[] = $package_name;129130$package_symbols = $this->packageMap[$package_name];131foreach ($package_symbols as $package_symbol) {132$handled[$package_symbol] = true;133}134}135}136137return $packaged;138}139140public function getResourceDataForName($resource_name) {141return $this->resources->getResourceData($resource_name);142}143144public function getResourceNamesForPackageName($package_name) {145$package_symbols = idx($this->packageMap, $package_name);146if (!$package_symbols) {147return null;148}149150$resource_names = array();151foreach ($package_symbols as $symbol) {152$resource_names[] = $this->hashMap[$this->symbolMap[$symbol]];153}154155return $resource_names;156}157158159/**160* Get the epoch timestamp of the last modification time of a symbol.161*162* @param string Resource symbol to lookup.163* @return int Epoch timestamp of last resource modification.164*/165public function getModifiedTimeForName($name) {166if ($this->isPackageResource($name)) {167$names = array();168foreach ($this->packageMap[$name] as $symbol) {169$names[] = $this->getResourceNameForSymbol($symbol);170}171} else {172$names = array($name);173}174175$mtime = 0;176foreach ($names as $name) {177$mtime = max($mtime, $this->resources->getResourceModifiedTime($name));178}179180return $mtime;181}182183184/**185* Return the absolute URI for the resource associated with a symbol. This186* method is fairly low-level and ignores packaging.187*188* @param string Resource symbol to lookup.189* @return string|null Resource URI, or null if the symbol is unknown.190*/191public function getURIForSymbol($symbol) {192$hash = idx($this->symbolMap, $symbol);193return $this->getURIForHash($hash);194}195196197/**198* Return the absolute URI for the resource associated with a resource name.199* This method is fairly low-level and ignores packaging.200*201* @param string Resource name to lookup.202* @return string|null Resource URI, or null if the name is unknown.203*/204public function getURIForName($name) {205$hash = idx($this->nameMap, $name);206return $this->getURIForHash($hash);207}208209210public function getHashForName($name) {211return idx($this->nameMap, $name);212}213214215/**216* Return the absolute URI for a resource, identified by hash.217* This method is fairly low-level and ignores packaging.218*219* @param string Resource hash to lookup.220* @return string|null Resource URI, or null if the hash is unknown.221*/222private function getURIForHash($hash) {223if ($hash === null) {224return null;225}226return $this->resources->getResourceURI($hash, $this->hashMap[$hash]);227}228229230/**231* Return the resource symbols required by a named resource.232*233* @param string Resource name to lookup.234* @return list<string>|null List of required symbols, or null if the name235* is unknown.236*/237public function getRequiredSymbolsForName($name) {238$hash = idx($this->nameMap, $name);239if ($hash === null) {240return null;241}242return idx($this->requiresMap, $hash, array());243}244245246/**247* Return the resource name for a given symbol.248*249* @param string Resource symbol to lookup.250* @return string|null Resource name, or null if the symbol is unknown.251*/252public function getResourceNameForSymbol($symbol) {253$hash = idx($this->symbolMap, $symbol);254return idx($this->hashMap, $hash);255}256257public function isPackageResource($name) {258return isset($this->packageMap[$name]);259}260261public function getResourceTypeForName($name) {262return $this->resources->getResourceType($name);263}264265}266267268