y_key_exists($type, $this->assets)) { $this->assets[$type] = []; } // Check if any new file was added $this->parseRegistryFiles(); $eventChange = 'new'; $eventAsset = $asset; // Use "old" asset for "Changed" event, a "new" asset can be loaded by a name from the registry if (!empty($this->assets[$type][$asset->getName()])) { $eventChange = 'override'; $eventAsset = $this->assets[$type][$asset->getName()]; } $this->assets[$type][$asset->getName()] = $asset; $this->dispatchAssetChanged($type, $eventAsset, $eventChange); return $this; } /** * Remove Asset from registry. * * @param string $type Asset type, script or style * @param string $name Asset name * * @return self * * @since 4.0.0 */ public function remove(string $type, string $name): WebAssetRegistryInterface { // Check if any new file was added $this->parseRegistryFiles(); if (!empty($this->assets[$type][$name])) { $asset = $this->assets[$type][$name]; unset($this->assets[$type][$name]); $this->dispatchAssetChanged($type, $asset, 'remove'); } return $this; } /** * Check whether the asset exists in the registry. * * @param string $type Asset type, script or style * @param string $name Asset name * * @return boolean * * @since 4.0.0 */ public function exists(string $type, string $name): bool { // Check if any new file was added $this->parseRegistryFiles(); return !empty($this->assets[$type][$name]); } /** * Prepare new Asset instance. * * @param string $name The asset name * @param ?string $uri The URI for the asset * @param array $options Additional options for the asset * @param array $attributes Attributes for the asset * @param array $dependencies Asset dependencies * * @return WebAssetItem * * @since 4.0.0 */ public function createAsset( string $name, ?string $uri = null, array $options = [], array $attributes = [], array $dependencies = [] ): WebAssetItem { $nameSpace = \array_key_exists('namespace', $options) ? $options['namespace'] : __NAMESPACE__ . '\\AssetItem'; $className = \array_key_exists('class', $options) ? $options['class'] : null; if ($className && class_exists($nameSpace . '\\' . $className)) { $className = $nameSpace . '\\' . $className; return new $className($name, $uri, $options, $attributes, $dependencies); } return new WebAssetItem($name, $uri, $options, $attributes, $dependencies); } /** * Register new file with Asset(s) info * * @param string $path Relative path * * @return self * * @since 4.0.0 */ public function addRegistryFile(string $path): self { $path = Path::clean($path); if (isset($this->dataFilesNew[$path]) || isset($this->dataFilesParsed[$path])) { return $this; } if (is_file(JPATH_ROOT . '/' . $path)) { $this->dataFilesNew[$path] = $path; } return $this; } /** * Get a list of the registry files * * @return array * * @since 4.0.0 */ public function getRegistryFiles(): array { return array_values($this->dataFilesParsed + $this->dataFilesNew); } /** * Helper method to register new file with Template Asset(s) info * * @param string $template The template name * @param integer $client The application client id * * @return self * * @since 4.0.0 */ public function addTemplateRegistryFile(string $template, int $client): self { switch ($client) { case 0: $this->addRegistryFile('templates/' . $template . '/joomla.asset.json'); break; case 1: $this->addRegistryFile('administrator/templates/' . $template . '/joomla.asset.json'); break; default: break; } return $this; } /** * Helper method to register new file with Extension Asset(s) info * * @param string $name A full extension name, actually a name in the /media folder, eg: com_example, plg_system_example etc. * * @return self * * @since 4.0.0 */ public function addExtensionRegistryFile(string $name): self { $this->addRegistryFile('media/' . $name . '/joomla.asset.json'); return $this; } /** * Parse registered files * * @return void * * @since 4.0.0 */ protected function parseRegistryFiles() { if (!$this->dataFilesNew) { return; } $paths = $this->dataFilesNew; $this->dataFilesNew = []; foreach ($paths as $path) { // Parse only if the file was not parsed already if (empty($this->dataFilesParsed[$path])) { $this->parseRegistryFile($path); // Mark the file as parsed $this->dataFilesParsed[$path] = $path; } } } /** * Parse registry file * * @param string $path Relative path to the data file * * @return void * * @throws \RuntimeException If file is empty or invalid * * @since 4.0.0 */ protected function parseRegistryFile($path) { $data = file_get_contents(JPATH_ROOT . '/' . $path); $data = $data ? json_decode($data, true) : null; if ($data === null) { throw new \RuntimeException(\sprintf('Asset registry file "%s" contains invalid JSON', $path)); } // Check if asset field exists and contains data. If it doesn't - we can just bail here. if (empty($data['assets'])) { return; } // Keep source info $assetSource = [ 'registryFile' => $path, ]; $namespace = \array_key_exists('namespace', $data) ? $data['namespace'] : null; // Prepare WebAssetItem instances foreach ($data['assets'] as $i => $item) { if (empty($item['name'])) { throw new \RuntimeException( \sprintf('Failed parsing asset registry file "%s". Property "name" is required for asset index "%s"', $path, $i) ); } if (empty($item['type'])) { throw new \RuntimeException( \sprintf('Failed parsing asset registry file "%s". Property "type" is required for asset "%s"', $path, $item['name']) ); } $item['type'] = strtolower($item['type']); $name = $item['name']; $uri = $item['uri'] ?? ''; $options = $item; $options['assetSource'] = $assetSource; unset($options['uri'], $options['name']); // Inheriting the Namespace if ($namespace && !\array_key_exists('namespace', $options)) { $options['namespace'] = $namespace; } $assetItem = $this->createAsset($name, $uri, $options); $this->add($item['type'], $assetItem); } } /** * Dispatch an event to notify listeners about asset changes: new, remove, override * Events: * - onWebAssetRegistryChangedAssetNew When new asset added to the registry * - onWebAssetRegistryChangedAssetOverride When the asset overridden * - onWebAssetRegistryChangedAssetRemove When new asset was removed from the registry * * @param string $type Asset type, script or style * @param WebAssetItemInterface $asset Asset instance * @param string $change A type of change: new, remove, override * * @return void * * @since 4.0.0 */ protected function dispatchAssetChanged(string $type, WebAssetItemInterface $asset, string $change) { // Trigger the event $event = AbstractEvent::create( 'onWebAssetRegistryChangedAsset' . ucfirst($change), [ 'eventClass' => WebAssetRegistryAssetChanged::class, 'subject' => $this, 'assetType' => $type, 'asset' => $asset, 'change' => $change, ] ); $this->getDispatcher()->dispatch($event->getName(), $event); } } y_key_exists($type, $this->assets)) { $this->assets[$type] = []; } // Check if any new file was added $this->parseRegistryFiles(); $eventChange = 'new'; $eventAsset = $asset; // Use "old" asset for "Changed" event, a "new" asset can be loaded by a name from the registry if (!empty($this->assets[$type][$asset->getName()])) { $eventChange = 'override'; $eventAsset = $this->assets[$type][$asset->getName()]; } $this->assets[$type][$asset->getName()] = $asset; $this->dispatchAssetChanged($type, $eventAsset, $eventChange); return $this; } /** * Remove Asset from registry. * * @param string $type Asset type, script or style * @param string $name Asset name * * @return self * * @since 4.0.0 */ public function remove(string $type, string $name): WebAssetRegistryInterface { // Check if any new file was added $this->parseRegistryFiles(); if (!empty($this->assets[$type][$name])) { $asset = $this->assets[$type][$name]; unset($this->assets[$type][$name]); $this->dispatchAssetChanged($type, $asset, 'remove'); } return $this; } /** * Check whether the asset exists in the registry. * * @param string $type Asset type, script or style * @param string $name Asset name * * @return boolean * * @since 4.0.0 */ public function exists(string $type, string $name): bool { // Check if any new file was added $this->parseRegistryFiles(); return !empty($this->assets[$type][$name]); } /** * Prepare new Asset instance. * * @param string $name The asset name * @param ?string $uri The URI for the asset * @param array $options Additional options for the asset * @param array $attributes Attributes for the asset * @param array $dependencies Asset dependencies * * @return WebAssetItem * * @since 4.0.0 */ public function createAsset( string $name, ?string $uri = null, array $options = [], array $attributes = [], array $dependencies = [] ): WebAssetItem { $nameSpace = \array_key_exists('namespace', $options) ? $options['namespace'] : __NAMESPACE__ . '\\AssetItem'; $className = \array_key_exists('class', $options) ? $options['class'] : null; if ($className && class_exists($nameSpace . '\\' . $className)) { $className = $nameSpace . '\\' . $className; return new $className($name, $uri, $options, $attributes, $dependencies); } return new WebAssetItem($name, $uri, $options, $attributes, $dependencies); } /** * Register new file with Asset(s) info * * @param string $path Relative path * * @return self * * @since 4.0.0 */ public function addRegistryFile(string $path): self { $path = Path::clean($path); if (isset($this->dataFilesNew[$path]) || isset($this->dataFilesParsed[$path])) { return $this; } if (is_file(JPATH_ROOT . '/' . $path)) { $this->dataFilesNew[$path] = $path; } return $this; } /** * Get a list of the registry files * * @return array * * @since 4.0.0 */ public function getRegistryFiles(): array { return array_values($this->dataFilesParsed + $this->dataFilesNew); } /** * Helper method to register new file with Template Asset(s) info * * @param string $template The template name * @param integer $client The application client id * * @return self * * @since 4.0.0 */ public function addTemplateRegistryFile(string $template, int $client): self { switch ($client) { case 0: $this->addRegistryFile('templates/' . $template . '/joomla.asset.json'); break; case 1: $this->addRegistryFile('administrator/templates/' . $template . '/joomla.asset.json'); break; default: break; } return $this; } /** * Helper method to register new file with Extension Asset(s) info * * @param string $name A full extension name, actually a name in the /media folder, eg: com_example, plg_system_example etc. * * @return self * * @since 4.0.0 */ public function addExtensionRegistryFile(string $name): self { $this->addRegistryFile('media/' . $name . '/joomla.asset.json'); return $this; } /** * Parse registered files * * @return void * * @since 4.0.0 */ protected function parseRegistryFiles() { if (!$this->dataFilesNew) { return; } $paths = $this->dataFilesNew; $this->dataFilesNew = []; foreach ($paths as $path) { // Parse only if the file was not parsed already if (empty($this->dataFilesParsed[$path])) { $this->parseRegistryFile($path); // Mark the file as parsed $this->dataFilesParsed[$path] = $path; } } } /** * Parse registry file * * @param string $path Relative path to the data file * * @return void * * @throws \RuntimeException If file is empty or invalid * * @since 4.0.0 */ protected function parseRegistryFile($path) { $data = file_get_contents(JPATH_ROOT . '/' . $path); $data = $data ? json_decode($data, true) : null; if ($data === null) { throw new \RuntimeException(\sprintf('Asset registry file "%s" contains invalid JSON', $path)); } // Check if asset field exists and contains data. If it doesn't - we can just bail here. if (empty($data['assets'])) { return; } // Keep source info $assetSource = [ 'registryFile' => $path, ]; $namespace = \array_key_exists('namespace', $data) ? $data['namespace'] : null; // Prepare WebAssetItem instances foreach ($data['assets'] as $i => $item) { if (empty($item['name'])) { throw new \RuntimeException( \sprintf('Failed parsing asset registry file "%s". Property "name" is required for asset index "%s"', $path, $i) ); } if (empty($item['type'])) { throw new \RuntimeException( \sprintf('Failed parsing asset registry file "%s". Property "type" is required for asset "%s"', $path, $item['name']) ); } $item['type'] = strtolower($item['type']); $name = $item['name']; $uri = $item['uri'] ?? ''; $options = $item; $options['assetSource'] = $assetSource; unset($options['uri'], $options['name']); // Inheriting the Namespace if ($namespace && !\array_key_exists('namespace', $options)) { $options['namespace'] = $namespace; } $assetItem = $this->createAsset($name, $uri, $options); $this->add($item['type'], $assetItem); } } /** * Dispatch an event to notify listeners about asset changes: new, remove, override * Events: * - onWebAssetRegistryChangedAssetNew When new asset added to the registry * - onWebAssetRegistryChangedAssetOverride When the asset overridden * - onWebAssetRegistryChangedAssetRemove When new asset was removed from the registry * * @param string $type Asset type, script or style * @param WebAssetItemInterface $asset Asset instance * @param string $change A type of change: new, remove, override * * @return void * * @since 4.0.0 */ protected function dispatchAssetChanged(string $type, WebAssetItemInterface $asset, string $change) { // Trigger the event $event = AbstractEvent::create( 'onWebAssetRegistryChangedAsset' . ucfirst($change), [ 'eventClass' => WebAssetRegistryAssetChanged::class, 'subject' => $this, 'assetType' => $type, 'asset' => $asset, 'change' => $change, ] ); $this->getDispatcher()->dispatch($event->getName(), $event); } } An Error Occurred: Whoops, looks like something went wrong.

Sorry, there was a problem we could not recover from.

The server returned a "500 - Whoops, looks like something went wrong."

Help me resolve this