diff --git a/lang/de_de.lang b/lang/de_de.lang
index ea454cf..653b0b1 100644
--- a/lang/de_de.lang
+++ b/lang/de_de.lang
@@ -133,11 +133,24 @@ settings_saved = Einstellungen erfolgreich gespeichert
upload = Upload
upload_module = Modul "{0}" hochladen
upload_template = Template "{0}" hochladen
+upload_class = Klasse hochladen
upload_success = "{0}" wurde erfolgreich zu "{1}" hochgeladen
upload_error = Fehler beim Hochladen
upload_missing_data = Bitte alle Pflichtfelder ausfüllen
no_local_modules = Keine lokalen Module gefunden
no_local_templates = Keine lokalen Templates gefunden
+no_local_classes = Keine lokalen Klassen gefunden
+upload_no_repos = Keine Repositories konfiguriert. Bitte fügen Sie zuerst Repositories hinzu.
+upload_select_repo = Repository auswählen
+upload_choose_repo = -- Repository wählen --
+upload_select_class = Klasse auswählen
+upload_choose_class = -- Klasse wählen --
+upload_commit_message = Commit-Nachricht
+upload_commit_placeholder = Beschreibung der Änderungen...
+upload_class_to_github = Klasse zu GitHub hochladen
+local_classes_overview = Lokale Klassen-Übersicht
+class_files = Dateien
+class_installed = Installiert
github_owner = GitHub Besitzer
github_repo = Repository Name
github_branch = Branch
@@ -164,6 +177,30 @@ upload_author = Standard Autor
upload_author_help = Dein Name für die Metadaten
upload_settings_missing = Upload-Einstellungen sind nicht vollständig konfiguriert. Bitte konfiguriere Owner und Repository in den
+# Overview
+overview_title = GitHub Installer - Übersicht
+overview_repositories = Repositories
+overview_repositories_desc = Verwalten Sie GitHub Repositories für Module, Templates und Klassen.
+overview_manage_repositories = Repositories verwalten
+overview_install = Installieren
+overview_install_desc = Installieren Sie Module, Templates und Klassen von GitHub.
+overview_upload = Upload
+overview_upload_desc = Laden Sie Ihre eigenen Inhalte zu GitHub hoch.
+overview_modules_templates = Module/Templates
+overview_classes = Klassen
+overview_class_management = Klassen-Management
+overview_installation = Installation
+overview_class_install_desc = Klassen werden automatisch im Verzeichnis project/lib/gitClasses/KlassenName/ installiert.
+overview_structure = Struktur
+overview_class_structure_1 = Jede Klasse erhält einen eigenen Ordner
+overview_class_structure_2 = Metadaten werden in config.yml gespeichert
+overview_class_structure_3 = Zusätzliche Dateien werden mit übertragen
+overview_class_upload_desc = Lokale Klassen können zu GitHub Repositories hochgeladen werden.
+overview_management = Verwaltung
+overview_cache_desc = Repository-Daten werden gecacht für bessere Performance.
+overview_manage_cache = Cache verwalten
+overview_settings_desc = GitHub Token und Cache-Einstellungen konfigurieren.
+
# General
loading = Lade...
error_occurred = Ein Fehler ist aufgetreten
@@ -178,3 +215,6 @@ save = Speichern
edit = Bearbeiten
delete = Löschen
back = Zurück
+delete_class_confirm = Möchten Sie die Klasse "%s" wirklich löschen? Ein Backup wird erstellt.
+class_deleted = Klasse wurde erfolgreich gelöscht
+delete_failed = Löschen fehlgeschlagen
diff --git a/lang/en_gb.lang b/lang/en_gb.lang
index 6bd8e54..9f6e588 100644
--- a/lang/en_gb.lang
+++ b/lang/en_gb.lang
@@ -49,6 +49,32 @@ module_actions = Actions
module_details = Details
module_info = Module Information
+# Classes
+classes_title = Classes
+classes_select_repo = Select Repository
+classes_choose_repo = -- Choose Repository --
+classes_no_repos = No repositories configured. Please add repositories first.
+classes_loading = Loading classes...
+classes_no_classes = No classes found in this repository
+classes_install = Install
+classes_install_confirm = Install class "{0}"?
+classes_installed_success = Class installed successfully
+classes_install_error = Error installing class
+classes_update = Reload
+classes_update_confirm = Reload class "{0}"?
+classes_updated_success = Class successfully reloaded
+classes_update_error = Error reloading class
+class_name = Name
+class_title = Title
+class_description = Description
+class_version = Version
+class_author = Author
+class_namespace = Namespace
+class_target_directory = Target Directory
+class_actions = Actions
+class_details = Details
+class_info = Class Information
+
# Templates
templates_title = Templates
templates_select_repo = Select Repository
@@ -60,6 +86,10 @@ templates_install = Install
templates_install_confirm = Install template "{0}"?
templates_installed_success = Template installed successfully
templates_install_error = Error installing template
+templates_update = Reload
+templates_update_confirm = Reload template "{0}"?
+templates_updated_success = Template successfully reloaded
+templates_update_error = Error reloading template
template_name = Name
template_title = Title
template_description = Description
@@ -97,11 +127,24 @@ settings_saved = Settings saved successfully
upload = Upload
upload_module = Upload module "{0}"
upload_template = Upload template "{0}"
+upload_class = Upload class
upload_success = "{0}" was successfully uploaded to "{1}"
upload_error = Upload error
upload_missing_data = Please fill all required fields
no_local_modules = No local modules found
no_local_templates = No local templates found
+no_local_classes = No local classes found
+upload_no_repos = No repositories configured. Please add repositories first.
+upload_select_repo = Select Repository
+upload_choose_repo = -- Choose Repository --
+upload_select_class = Select Class
+upload_choose_class = -- Choose Class --
+upload_commit_message = Commit Message
+upload_commit_placeholder = Description of changes...
+upload_class_to_github = Upload Class to GitHub
+local_classes_overview = Local Classes Overview
+class_files = Files
+class_installed = Installed
github_owner = GitHub Owner
github_repo = Repository Name
github_branch = Branch
@@ -128,6 +171,30 @@ upload_author = Default Author
upload_author_help = Your name for metadata
upload_settings_missing = Upload settings are not fully configured. Please configure Owner and Repository in the
+# Overview
+overview_title = GitHub Installer - Overview
+overview_repositories = Repositories
+overview_repositories_desc = Manage GitHub repositories for modules, templates and classes.
+overview_manage_repositories = Manage Repositories
+overview_install = Install
+overview_install_desc = Install modules, templates and classes from GitHub.
+overview_upload = Upload
+overview_upload_desc = Upload your own content to GitHub.
+overview_modules_templates = Modules/Templates
+overview_classes = Classes
+overview_class_management = Class Management
+overview_installation = Installation
+overview_class_install_desc = Classes are automatically installed to the project/lib/gitClasses/ClassName/ directory.
+overview_structure = Structure
+overview_class_structure_1 = Each class gets its own folder
+overview_class_structure_2 = Metadata is stored in config.yml
+overview_class_structure_3 = Additional files are transferred as well
+overview_class_upload_desc = Local classes can be uploaded to GitHub repositories.
+overview_management = Management
+overview_cache_desc = Repository data is cached for better performance.
+overview_manage_cache = Manage Cache
+overview_settings_desc = Configure GitHub token and cache settings.
+
# General
loading = Loading...
error_occurred = An error occurred
@@ -142,3 +209,6 @@ save = Save
edit = Edit
delete = Delete
back = Back
+delete_class_confirm = Do you really want to delete the class "%s"? A backup will be created.
+class_deleted = Class was successfully deleted
+delete_failed = Delete failed
diff --git a/lib/ClassManager.php b/lib/ClassManager.php
new file mode 100644
index 0000000..25f6c3b
--- /dev/null
+++ b/lib/ClassManager.php
@@ -0,0 +1,415 @@
+github = new GitHubApi();
+ $this->repoManager = new RepositoryManager();
+ $this->projectLibPath = rex_path::addon('project') . 'lib/gitClasses/';
+ }
+
+ /**
+ * Klasse installieren
+ */
+ public function installClass(string $repoKey, string $className): bool
+ {
+ $repositories = $this->repoManager->getRepositories();
+
+ if (!isset($repositories[$repoKey])) {
+ throw new \Exception('Repository not found');
+ }
+
+ $repo = $repositories[$repoKey];
+ $classes = $this->repoManager->getClasses($repoKey);
+
+ if (!isset($classes[$className])) {
+ throw new \Exception('Class not found in repository');
+ }
+
+ $classData = $classes[$className];
+ $targetDir = $this->projectLibPath . $className . '/';
+
+ // Zielverzeichnis erstellen
+ if (!rex_dir::create($targetDir)) {
+ throw new \Exception('Cannot create target directory: ' . $targetDir);
+ }
+
+ // Hauptklassen-Datei installieren
+ $filename = $classData['filename'] ?? $className . '.php';
+ $targetFile = $targetDir . $filename;
+
+ if (!rex_file::put($targetFile, $classData['content'])) {
+ throw new \Exception('Cannot write class file: ' . $targetFile);
+ }
+
+ // Zusätzliche Dateien installieren (falls vorhanden)
+ $this->installAdditionalFiles($repo, $className, $targetDir);
+
+ // Config-Datei erstellen für Metadaten
+ $this->createConfigFile($targetDir, $classData);
+
+ return true;
+ }
+
+ /**
+ * Klasse aktualisieren
+ */
+ public function updateClass(string $repoKey, string $className): bool
+ {
+ $targetDir = $this->projectLibPath . $className . '/';
+
+ if (!is_dir($targetDir)) {
+ throw new \Exception('Class not installed locally');
+ }
+
+ // Backup erstellen
+ $backupDir = $targetDir . '.backup_' . date('Y-m-d_H-i-s') . '/';
+ if (!rex_dir::copy($targetDir, $backupDir)) {
+ throw new \Exception('Cannot create backup');
+ }
+
+ try {
+ // Klasse neu installieren
+ $result = $this->installClass($repoKey, $className);
+
+ // Backup löschen bei Erfolg
+ rex_dir::delete($backupDir);
+
+ return $result;
+
+ } catch (\Exception $e) {
+ // Bei Fehler: Backup wiederherstellen
+ rex_dir::delete($targetDir);
+ rex_dir::copy($backupDir, $targetDir);
+ rex_dir::delete($backupDir);
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Klasse zu GitHub hochladen
+ */
+ public function uploadClass(string $repoKey, string $className, string $commitMessage = ''): bool
+ {
+ $repositories = $this->repoManager->getRepositories();
+
+ if (!isset($repositories[$repoKey])) {
+ throw new \Exception('Repository not found');
+ }
+
+ $repo = $repositories[$repoKey];
+ $classDir = $this->projectLibPath . $className . '/';
+
+ if (!is_dir($classDir)) {
+ throw new \Exception('Class directory not found: ' . $classDir);
+ }
+
+ // Alle Dateien im Klassen-Verzeichnis hochladen
+ $files = $this->getClassFiles($classDir);
+
+ if (empty($files)) {
+ throw new \Exception('No files found in class directory');
+ }
+
+ $commitMessage = $commitMessage ?: "Update class {$className}";
+
+ foreach ($files as $relativePath => $content) {
+ $githubPath = "classes/{$className}/{$relativePath}";
+
+ $this->github->uploadFile(
+ $repo['owner'],
+ $repo['repo'],
+ $githubPath,
+ $content,
+ $commitMessage,
+ $repo['branch'] ?? 'main'
+ );
+ }
+
+ return true;
+ }
+
+
+
+ /**
+ * Alle lokalen Klassen abrufen
+ */
+ public function getLocalClasses(): array
+ {
+ $classes = [];
+
+ if (!is_dir($this->projectLibPath)) {
+ return $classes;
+ }
+
+ $directories = scandir($this->projectLibPath);
+
+ foreach ($directories as $dir) {
+ if ($dir === '.' || $dir === '..') {
+ continue;
+ }
+
+ $classDir = $this->projectLibPath . $dir . '/';
+
+ if (!is_dir($classDir)) {
+ continue;
+ }
+
+ $classData = $this->analyzeLocalClass($dir, $classDir);
+ if ($classData) {
+ $classes[$dir] = $classData;
+ }
+ }
+
+ return $classes;
+ }
+
+ /**
+ * Zusätzliche Dateien aus Repository installieren
+ */
+ private function installAdditionalFiles(array $repo, string $className, string $targetDir): void
+ {
+ try {
+ $contents = $this->github->getRepositoryContents(
+ $repo['owner'],
+ $repo['repo'],
+ "classes/{$className}",
+ $repo['branch'] ?? 'main'
+ );
+
+ foreach ($contents as $item) {
+ if ($item['type'] === 'file' && $item['name'] !== ($className . '.php')) {
+ try {
+ $content = $this->github->getFileContent(
+ $repo['owner'],
+ $repo['repo'],
+ "classes/{$className}/{$item['name']}",
+ $repo['branch'] ?? 'main'
+ );
+
+ rex_file::put($targetDir . $item['name'], $content);
+
+ } catch (\Exception $e) {
+ // Einzelne Datei konnte nicht geladen werden - weiter machen
+ error_log("Could not install additional file {$item['name']}: " . $e->getMessage());
+ }
+ }
+ }
+
+ } catch (\Exception $e) {
+ // Keine zusätzlichen Dateien vorhanden oder Fehler - kein Problem
+ }
+ }
+
+ /**
+ * Config-Datei für Metadaten erstellen
+ */
+ private function createConfigFile(string $targetDir, array $classData): void
+ {
+ $config = [
+ 'title' => $classData['title'] ?? '',
+ 'description' => $classData['description'] ?? '',
+ 'version' => $classData['version'] ?? '1.0.0',
+ 'author' => $classData['author'] ?? '',
+ 'filename' => $classData['filename'] ?? '',
+ 'namespace' => $classData['namespace'] ?? '',
+ 'installed_at' => date('Y-m-d H:i:s'),
+ 'source_path' => $classData['path'] ?? ''
+ ];
+
+ $yamlContent = "# Class Configuration\n";
+ foreach ($config as $key => $value) {
+ if ($value !== '' && $value !== null) {
+ $yamlContent .= "{$key}: " . (is_string($value) ? '"' . addslashes($value) . '"' : $value) . "\n";
+ }
+ }
+
+ rex_file::put($targetDir . 'config.yml', $yamlContent);
+ }
+
+ /**
+ * Alle Dateien in einem Klassen-Verzeichnis abrufen
+ */
+ private function getClassFiles(string $classDir): array
+ {
+ $files = [];
+ $iterator = new \RecursiveIteratorIterator(
+ new \RecursiveDirectoryIterator($classDir)
+ );
+
+ foreach ($iterator as $file) {
+ if ($file->isFile()) {
+ $relativePath = str_replace($classDir, '', $file->getPathname());
+ $relativePath = str_replace('\\', '/', $relativePath); // Windows compatibility
+
+ $content = rex_file::get($file->getPathname());
+ if ($content !== false) {
+ $files[$relativePath] = $content;
+ }
+ }
+ }
+
+ return $files;
+ }
+
+ /**
+ * Lokale Klasse analysieren
+ */
+ private function analyzeLocalClass(string $className, string $classDir): ?array
+ {
+ // Config-Datei suchen
+ $configFile = $classDir . 'config.yml';
+ $config = [];
+
+ if (file_exists($configFile)) {
+ $configContent = rex_file::get($configFile);
+ if ($configContent) {
+ $config = $this->parseSimpleYaml($configContent);
+ }
+ }
+
+ // Hauptklassen-Datei finden
+ $phpFiles = glob($classDir . '*.php');
+ $mainFile = null;
+
+ if (!empty($config['filename'])) {
+ $mainFile = $classDir . $config['filename'];
+ } elseif (file_exists($classDir . $className . '.php')) {
+ $mainFile = $classDir . $className . '.php';
+ } elseif (!empty($phpFiles)) {
+ $mainFile = $phpFiles[0];
+ }
+
+ if (!$mainFile || !file_exists($mainFile)) {
+ return null;
+ }
+
+ $content = rex_file::get($mainFile);
+ if (!$content) {
+ return null;
+ }
+
+ return [
+ 'title' => $config['title'] ?? $className,
+ 'description' => $config['description'] ?? $this->extractClassDescription($content),
+ 'version' => $config['version'] ?? $this->extractClassVersion($content) ?? '1.0.0',
+ 'author' => $config['author'] ?? $this->extractClassAuthor($content),
+ 'filename' => basename($mainFile),
+ 'namespace' => $config['namespace'] ?? $this->extractNamespace($content),
+ 'installed_at' => $config['installed_at'] ?? (file_exists($configFile) ? date('Y-m-d H:i:s', filemtime($configFile)) : ''),
+ 'source_path' => $config['source_path'] ?? '',
+ 'local_path' => $classDir,
+ 'has_config' => file_exists($configFile),
+ 'file_count' => count(glob($classDir . '*'))
+ ];
+ }
+
+ /**
+ * Einfacher YAML-Parser
+ */
+ private function parseSimpleYaml(string $content): array
+ {
+ $result = [];
+ $lines = explode("\n", $content);
+
+ foreach ($lines as $line) {
+ $line = trim($line);
+ if (empty($line) || strpos($line, '#') === 0) {
+ continue;
+ }
+
+ if (strpos($line, ':') !== false) {
+ [$key, $value] = explode(':', $line, 2);
+ $key = trim($key);
+ $value = trim($value, ' "\'');
+
+ if ($value === 'true') {
+ $value = true;
+ } elseif ($value === 'false') {
+ $value = false;
+ } elseif (is_numeric($value)) {
+ $value = is_float($value) ? (float)$value : (int)$value;
+ }
+
+ $result[$key] = $value;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Namespace aus PHP-Code extrahieren
+ */
+ private function extractNamespace(string $content): string
+ {
+ if (preg_match('/namespace\s+([^;]+);/', $content, $matches)) {
+ return trim($matches[1]);
+ }
+
+ return '';
+ }
+
+ /**
+ * Beschreibung aus PHP-Kommentaren extrahieren
+ */
+ private function extractClassDescription(string $content): string
+ {
+ if (preg_match('/@description\s+(.+)/i', $content, $matches)) {
+ return trim($matches[1]);
+ }
+
+ if (preg_match('/\/\*\*(.*?)\*\//s', $content, $matches)) {
+ $comment = $matches[1];
+ $lines = explode("\n", $comment);
+
+ foreach ($lines as $line) {
+ $line = trim($line, " \t*");
+ if (!empty($line) && !preg_match('/@\w+/', $line)) {
+ return substr($line, 0, 200);
+ }
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * Version aus PHP-Kommentaren extrahieren
+ */
+ private function extractClassVersion(string $content): string
+ {
+ if (preg_match('/@version\s+(.+)/i', $content, $matches)) {
+ return trim($matches[1]);
+ }
+
+ return '';
+ }
+
+ /**
+ * Autor aus PHP-Kommentaren extrahieren
+ */
+ private function extractClassAuthor(string $content): string
+ {
+ if (preg_match('/@author\s+(.+)/i', $content, $matches)) {
+ return trim($matches[1]);
+ }
+
+ return '';
+ }
+}
\ No newline at end of file
diff --git a/lib/GitHubApi.php b/lib/GitHubApi.php
index ead1d73..c51c8e0 100644
--- a/lib/GitHubApi.php
+++ b/lib/GitHubApi.php
@@ -240,4 +240,12 @@ public function createOrUpdateFile(string $owner, string $repo, string $path, st
return $this->makeRequest($endpoint, 'PUT', $data);
}
+
+ /**
+ * Alias für createOrUpdateFile
+ */
+ public function uploadFile(string $owner, string $repo, string $path, string $content, string $message, string $branch = 'main'): array
+ {
+ return $this->createOrUpdateFile($owner, $repo, $path, $content, $message, $branch);
+ }
}
diff --git a/lib/NewInstallManager.php b/lib/NewInstallManager.php
index 47207af..174097a 100644
--- a/lib/NewInstallManager.php
+++ b/lib/NewInstallManager.php
@@ -252,22 +252,11 @@ public function installClass(string $repoKey, string $className): bool
$targetDirectory = $classData['target_directory'] ?? 'lib';
$filename = $classData['filename'] ?? $className . '.php';
- // Ziel-Pfad bestimmen mit Verzeichnis-Struktur
- if ($targetDirectory === 'lib') {
- $basePath = \rex_path::addon('project') . 'lib/';
- } else {
- $basePath = \rex_path::addon('project') . $targetDirectory . '/';
- }
+ // Ziel-Pfad bestimmen - IMMER in gitClasses Unterordner
+ $basePath = \rex_path::addon('project') . 'lib/gitClasses/';
- // Wenn die Klasse aus einem Verzeichnis stammt, Verzeichnis-Struktur beibehalten
- if (str_contains($classData['path'], '/')) {
- // z.B. "classes/DemoHelper" -> "DemoHelper/"
- $classDirName = basename($classData['path']);
- $targetPath = $basePath . $classDirName . '/';
- } else {
- // Einzelne Datei direkt in lib/
- $targetPath = $basePath;
- }
+ // Jede Klasse bekommt ihren eigenen Ordner im gitClasses Verzeichnis
+ $targetPath = $basePath . $className . '/';
// Verzeichnis erstellen falls nicht vorhanden
if (!is_dir($targetPath)) {
diff --git a/lib/RepositoryManager.php b/lib/RepositoryManager.php
index 3652e98..5c05ed9 100644
--- a/lib/RepositoryManager.php
+++ b/lib/RepositoryManager.php
@@ -591,20 +591,13 @@ private function hasKeyField(string $table = 'module'): bool
public function getClassesWithStatus(string $repoKey): array
{
$classes = $this->getClasses($repoKey);
- $projectLibPath = \rex_path::addon('project') . 'lib/';
+ $gitClassesPath = \rex_path::addon('project') . 'lib/gitClasses/';
foreach ($classes as $className => &$classData) {
$filename = $classData['filename'] ?? $className . '.php';
- // Prüfung mit Verzeichnis-Struktur
- if (str_contains($classData['path'], '/')) {
- // z.B. "classes/DemoHelper" -> "lib/DemoHelper/DemoHelper.php"
- $classDirName = basename($classData['path']);
- $targetFile = $projectLibPath . $classDirName . '/' . $filename;
- } else {
- // Einzelne Datei direkt in lib/
- $targetFile = $projectLibPath . $filename;
- }
+ // Jede Klasse bekommt ihren eigenen Ordner im gitClasses Verzeichnis
+ $targetFile = $gitClassesPath . $className . '/' . $filename;
$classData['status'] = [
'installed' => file_exists($targetFile),
diff --git a/lib/UpdateManager.php b/lib/UpdateManager.php
index 552b65d..80c4347 100644
--- a/lib/UpdateManager.php
+++ b/lib/UpdateManager.php
@@ -314,22 +314,11 @@ public function updateClass(string $repoKey, string $className): bool
$targetDirectory = $classData['target_directory'] ?? 'lib';
$filename = $classData['filename'] ?? $className . '.php';
- // Ziel-Pfad bestimmen mit Verzeichnis-Struktur
- if ($targetDirectory === 'lib') {
- $basePath = \rex_path::addon('project') . 'lib/';
- } else {
- $basePath = \rex_path::addon('project') . $targetDirectory . '/';
- }
+ // Ziel-Pfad bestimmen - IMMER in gitClasses Unterordner
+ $basePath = \rex_path::addon('project') . 'lib/gitClasses/';
- // Wenn die Klasse aus einem Verzeichnis stammt, Verzeichnis-Struktur beibehalten
- if (str_contains($classData['path'], '/')) {
- // z.B. "classes/DemoHelper" -> "DemoHelper/"
- $classDirName = basename($classData['path']);
- $targetPath = $basePath . $classDirName . '/';
- } else {
- // Einzelne Datei direkt in lib/
- $targetPath = $basePath;
- }
+ // Jede Klasse bekommt ihren eigenen Ordner im gitClasses Verzeichnis
+ $targetPath = $basePath . $className . '/';
$targetFile = $targetPath . $filename;
diff --git a/package.yml b/package.yml
index b2a03c1..6be520f 100644
--- a/package.yml
+++ b/package.yml
@@ -11,6 +11,7 @@ page:
icon: rex-icon fa-github
pjax: false
subpages:
+ overview: {title: 'translate:overview_title', perm: 'github_installer[install]', icon: 'rex-icon fa-dashboard'}
repositories: {title: 'translate:repositories', perm: 'github_installer[config]', icon: 'rex-icon fa-github'}
modules: {title: 'translate:modules', perm: 'github_installer[install]', icon: 'rex-icon fa-puzzle-piece'}
templates: {title: 'translate:templates', perm: 'github_installer[install]', icon: 'rex-icon fa-file-code-o'}
diff --git a/pages/classes.php b/pages/classes.php
index 9efde8b..271b8f9 100644
--- a/pages/classes.php
+++ b/pages/classes.php
@@ -82,14 +82,15 @@
$isInstalled = $classData['status']['installed'];
$statusBadge = $isInstalled ? 'Installiert' : 'Neu';
- // Action Button
+ // Action Buttons
+ $actionButtons = '';
if ($isInstalled) {
- $actionButton = '';
} else {
- $actionButton = '';
@@ -109,7 +110,7 @@
' . $addon->i18n('overview_repositories_desc') . '
+ ' . $addon->i18n('overview_manage_repositories') . ' +' . $addon->i18n('overview_install_desc') . '
+ ' . $addon->i18n('modules') . ' + ' . $addon->i18n('templates') . ' + ' . $addon->i18n('classes_title') . ' +' . $addon->i18n('overview_upload_desc') . '
+ ' . $addon->i18n('overview_modules_templates') . ' + ' . $addon->i18n('overview_classes') . ' +' . $addon->i18n('overview_class_install_desc') . '
+ +' . $addon->i18n('overview_class_upload_desc') . '
+' . $addon->i18n('overview_cache_desc') . '
+ ' . $addon->i18n('overview_manage_cache') . ' + +' . $addon->i18n('overview_settings_desc') . '
+ ' . $addon->i18n('settings') . ' +