Fixes: Simplify PageController, fix config API, update deployment package (2026-02-17)
- Removed service dependencies from PageController constructor - Fixed AdminController config API signatures - Cleaned up Application.php resource loading - Updated template with proper resource includes - Simplified routes.php - Reduced analyticshub.zip from 50KB to 27KB - Status: Fixed and ready for redeployment
This commit is contained in:
51
STATUS.md
51
STATUS.md
@@ -1,7 +1,7 @@
|
|||||||
# Nextcloud Google Analytics Hub - Current Status
|
# Nextcloud Google Analytics Hub - Current Status
|
||||||
|
|
||||||
**Status**: ⏸ **PAUSED** - Waiting for deployment testing
|
**Status**: 🔧 **FIXED** - Ready for redeployment
|
||||||
**Last Update**: 2026-02-13 14:17 GMT
|
**Last Update**: 2026-02-17 14:23 GMT
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -218,6 +218,53 @@ return [
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Latest Fixes (2026-02-17)
|
||||||
|
|
||||||
|
### Issue: App not accessible after configuration
|
||||||
|
User reported:
|
||||||
|
- No entry appears in menu bar
|
||||||
|
- Redirect to dashboard when accessing `/apps/analyticshub`
|
||||||
|
|
||||||
|
### Root Causes Identified:
|
||||||
|
1. **PageController constructor failure**: Required GoogleAnalyticsService and LLMService injection, which weren't properly registered in DI container
|
||||||
|
2. **Incorrect config API usage**: AdminController was using `getAppValue('key', 'app', '')` instead of correct signature `getAppValue('app', 'key', '')`
|
||||||
|
3. **Template rendering**: Used 'admin' rendering mode instead of 'blank'
|
||||||
|
|
||||||
|
### Fixes Applied:
|
||||||
|
1. ✅ **Simplified PageController**:
|
||||||
|
- Removed service dependencies from constructor
|
||||||
|
- Uses only IConfig (core Nextcloud service)
|
||||||
|
- Graceful configuration checking without service dependencies
|
||||||
|
- Uses 'blank' rendering mode for clean admin interface
|
||||||
|
|
||||||
|
2. ✅ **Fixed AdminController config API**:
|
||||||
|
- Corrected all `getAppValue` calls: `getAppValue('analyticshub', 'key', '')`
|
||||||
|
- Corrected all `setAppValue` calls: `setAppValue('analyticshub', 'key', value)`
|
||||||
|
|
||||||
|
3. ✅ **Cleaned up Application.php**:
|
||||||
|
- Removed automatic script/style loading (caused issues)
|
||||||
|
- Resources now loaded in template only when needed
|
||||||
|
|
||||||
|
4. ✅ **Updated template**:
|
||||||
|
- Added proper script/style includes
|
||||||
|
- Removed manual CSRF token (handled by JavaScript with OC.requestToken)
|
||||||
|
|
||||||
|
5. ✅ **Simplified routes.php**:
|
||||||
|
- Removed redundant requirements fields
|
||||||
|
- Cleaner route definitions
|
||||||
|
|
||||||
|
### Files Modified:
|
||||||
|
- `lib/Controller/PageController.php` - Removed service dependencies, fixed rendering mode
|
||||||
|
- `lib/Controller/AdminController.php` - Fixed config API signatures
|
||||||
|
- `appinfo/Application.php` - Removed automatic resource loading
|
||||||
|
- `templates/admin.php` - Added proper resource includes, removed manual CSRF
|
||||||
|
- `appinfo/routes.php` - Cleaned up route definitions
|
||||||
|
|
||||||
|
### New Package:
|
||||||
|
- `analyticshub.zip` (27KB) - Ready for redeployment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## What Needs to Happen
|
## What Needs to Happen
|
||||||
|
|
||||||
**Before Further Development:**
|
**Before Further Development:**
|
||||||
|
|||||||
BIN
analyticshub.zip
BIN
analyticshub.zip
Binary file not shown.
@@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||||||
namespace OCA\AnalyticsHub\AppInfo;
|
namespace OCA\AnalyticsHub\AppInfo;
|
||||||
|
|
||||||
use OCP\AppFramework\App;
|
use OCP\AppFramework\App;
|
||||||
use OCP\Util;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application class for Mini-CMO Analytics Hub
|
* Application class for Mini-CMO Analytics Hub
|
||||||
@@ -18,9 +17,5 @@ class Application extends App {
|
|||||||
|
|
||||||
public function __construct(array $urlParams = []) {
|
public function __construct(array $urlParams = []) {
|
||||||
parent::__construct(self::APP_ID, $urlParams);
|
parent::__construct(self::APP_ID, $urlParams);
|
||||||
|
|
||||||
// Load scripts and styles for admin page
|
|
||||||
Util::addStyle(self::APP_ID, 'admin');
|
|
||||||
Util::addScript(self::APP_ID, 'admin');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,6 @@
|
|||||||
<php min-version="7.4"/>
|
<php min-version="7.4"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<navigation>
|
<navigation>
|
||||||
<admin>analyticshub.page.index</admin>
|
<admin>page#index</admin>
|
||||||
</navigation>
|
</navigation>
|
||||||
</info>
|
</info>
|
||||||
|
|||||||
@@ -10,24 +10,22 @@ namespace OCA\AnalyticsHub;
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'routes' => [
|
'routes' => [
|
||||||
// Admin routes
|
// Main page route
|
||||||
[
|
[
|
||||||
'name' => 'page#index',
|
'name' => 'page#index',
|
||||||
'url' => '/',
|
'url' => '/',
|
||||||
'verb' => 'GET',
|
'verb' => 'GET',
|
||||||
'requirements' => [],
|
|
||||||
],
|
],
|
||||||
|
// Admin configuration routes (AJAX)
|
||||||
[
|
[
|
||||||
'name' => 'admin#load',
|
'name' => 'admin#load',
|
||||||
'url' => '/admin/load',
|
'url' => '/admin/load',
|
||||||
'verb' => 'GET',
|
'verb' => 'GET',
|
||||||
'requirements' => [],
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'name' => 'admin#save',
|
'name' => 'admin#save',
|
||||||
'url' => '/admin/save',
|
'url' => '/admin/save',
|
||||||
'verb' => 'POST',
|
'verb' => 'POST',
|
||||||
'requirements' => [],
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ class AdminController {
|
|||||||
* Load configuration
|
* Load configuration
|
||||||
*/
|
*/
|
||||||
public function load(): JSONResponse {
|
public function load(): JSONResponse {
|
||||||
$clientId = $this->config->getAppValue('google_client_id', 'analyticshub', '');
|
$clientId = $this->config->getAppValue('analyticshub', 'google_client_id', '');
|
||||||
$apiKey = $this->config->getAppValue('anthropic_api_key', 'analyticshub', '');
|
$apiKey = $this->config->getAppValue('analyticshub', 'anthropic_api_key', '');
|
||||||
$llmEndpoint = $this->config->getAppValue('llm_api_endpoint', 'analyticshub', '');
|
$llmEndpoint = $this->config->getAppValue('analyticshub', 'llm_api_endpoint', '');
|
||||||
$llmModel = $this->config->getAppValue('llm_model', 'analyticshub', '');
|
$llmModel = $this->config->getAppValue('analyticshub', 'llm_model', '');
|
||||||
$refreshToken = $this->config->getAppValue('google_refresh_token', 'analyticshub', '');
|
$refreshToken = $this->config->getAppValue('analyticshub', 'google_refresh_token', '');
|
||||||
|
|
||||||
// Check if configured
|
// Check if configured
|
||||||
$isConfigured = !empty($clientId) && !empty($apiKey) && !empty($refreshToken);
|
$isConfigured = !empty($clientId) && !empty($apiKey) && !empty($refreshToken);
|
||||||
@@ -92,22 +92,22 @@ class AdminController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save configuration
|
// Save configuration
|
||||||
$this->config->setAppValue('google_client_id', 'analyticshub', $clientId);
|
$this->config->setAppValue('analyticshub', 'google_client_id', $clientId);
|
||||||
$this->config->setAppValue('google_client_secret', 'analyticshub', $clientSecret);
|
$this->config->setAppValue('analyticshub', 'google_client_secret', $clientSecret);
|
||||||
|
|
||||||
if (!empty($refreshToken)) {
|
if (!empty($refreshToken)) {
|
||||||
$this->config->setAppValue('google_refresh_token', 'analyticshub', $refreshToken);
|
$this->config->setAppValue('analyticshub', 'google_refresh_token', $refreshToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($llmEndpoint)) {
|
if (!empty($llmEndpoint)) {
|
||||||
$this->config->setAppValue('llm_api_endpoint', 'analyticshub', $llmEndpoint);
|
$this->config->setAppValue('analyticshub', 'llm_api_endpoint', $llmEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($llmModel)) {
|
if (!empty($llmModel)) {
|
||||||
$this->config->setAppValue('llm_model', 'analyticshub', $llmModel);
|
$this->config->setAppValue('analyticshub', 'llm_model', $llmModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->config->setAppValue('anthropic_api_key', 'analyticshub', $apiKey);
|
$this->config->setAppValue('analyticshub', 'anthropic_api_key', $apiKey);
|
||||||
|
|
||||||
// Check if fully configured
|
// Check if fully configured
|
||||||
$isConfigured = !empty($clientId) && !empty($clientSecret) && !empty($apiKey) && !empty($refreshToken);
|
$isConfigured = !empty($clientId) && !empty($clientSecret) && !empty($apiKey) && !empty($refreshToken);
|
||||||
|
|||||||
@@ -7,81 +7,77 @@ namespace OCA\AnalyticsHub\Controller;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
use OCA\AnalyticsHub\Service\GoogleAnalyticsService;
|
|
||||||
use OCA\AnalyticsHub\Service\LLMService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin Settings Controller
|
* Admin Settings Controller
|
||||||
*
|
*
|
||||||
* @NoAdminRequired
|
* @AdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
class PageController extends \OCP\AppFramework\Controller {
|
class PageController extends \OCP\AppFramework\Controller {
|
||||||
|
|
||||||
protected $appName;
|
protected $appName;
|
||||||
protected $config;
|
protected $config;
|
||||||
protected $gaService;
|
|
||||||
protected $llmService;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $appName,
|
string $appName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
IConfig $config,
|
IConfig $config
|
||||||
GoogleAnalyticsService $gaService,
|
|
||||||
LLMService $llmService
|
|
||||||
) {
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->appName = $appName;
|
$this->appName = $appName;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->gaService = $gaService;
|
|
||||||
$this->llmService = $llmService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index page - render admin UI
|
* Index page - render admin UI
|
||||||
*
|
*
|
||||||
* @NoAdminRequired
|
* @AdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
*/
|
*/
|
||||||
public function index(): TemplateResponse {
|
public function index(): TemplateResponse {
|
||||||
// Check configuration status gracefully
|
// Get configuration values directly from config service
|
||||||
$isConfigured = false;
|
$clientId = $this->config->getAppValue('analyticshub', 'google_client_id', '');
|
||||||
$isGAConfigured = false;
|
$clientSecret = $this->config->getAppValue('analyticshub', 'google_client_secret', '');
|
||||||
$isLLMConfigured = false;
|
$refreshToken = $this->config->getAppValue('analyticshub', 'google_refresh_token', '');
|
||||||
|
$apiKey = $this->config->getAppValue('analyticshub', 'anthropic_api_key', '');
|
||||||
|
$llmEndpoint = $this->config->getAppValue('analyticshub', 'llm_api_endpoint', '');
|
||||||
|
$llmModel = $this->config->getAppValue('analyticshub', 'llm_model', '');
|
||||||
|
|
||||||
try {
|
// Check if configured
|
||||||
$isGAConfigured = $this->gaService->isConfigured();
|
$isConfigured = !empty($clientId) && !empty($clientSecret) && !empty($refreshToken) && !empty($apiKey);
|
||||||
$isLLMConfigured = $this->llmService->isConfigured();
|
$isGAConfigured = !empty($clientId) && !empty($clientSecret) && !empty($refreshToken);
|
||||||
$isConfigured = $isGAConfigured && $isLLMConfigured;
|
$isLLMConfigured = !empty($apiKey);
|
||||||
} catch (\Exception $e) {
|
|
||||||
// If service initialization fails, app is not configured
|
// Mask secrets for display
|
||||||
$isConfigured = false;
|
$maskedClientSecret = '';
|
||||||
|
if (!empty($clientSecret)) {
|
||||||
|
$maskedClientSecret = '••••••••••••••••';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get configuration values (masked for secrets)
|
$maskedRefreshToken = '';
|
||||||
$clientId = $this->config->getAppValue('google_client_id', 'analyticshub', '');
|
if (!empty($refreshToken)) {
|
||||||
$apiKey = $this->config->getAppValue('anthropic_api_key', 'analyticshub', '');
|
$maskedRefreshToken = substr($refreshToken, 0, 8) . '...' . substr($refreshToken, -4);
|
||||||
$llmEndpoint = $this->config->getAppValue('llm_api_endpoint', 'analyticshub', '');
|
}
|
||||||
$llmModel = $this->config->getAppValue('llm_model', 'analyticshub', '');
|
|
||||||
|
|
||||||
// Mask API key for display
|
|
||||||
$maskedApiKey = '';
|
$maskedApiKey = '';
|
||||||
if (!empty($apiKey)) {
|
if (!empty($apiKey)) {
|
||||||
$maskedApiKey = substr($apiKey, 0, 8) . '...' . substr($apiKey, -4);
|
$maskedApiKey = substr($apiKey, 0, 8) . '...' . substr($apiKey, -4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TemplateResponse($this->appName, 'admin', [
|
return new TemplateResponse('analyticshub', 'admin', [
|
||||||
'app_name' => $this->appName,
|
'app_name' => 'Mini-CMO Analytics Hub',
|
||||||
'version' => '1.0.0',
|
'version' => '1.0.0',
|
||||||
'status' => 'Ready for development',
|
'status' => $isConfigured ? 'Ready' : 'Configuration Required',
|
||||||
'is_configured' => $isConfigured,
|
'is_configured' => $isConfigured,
|
||||||
'is_ga_configured' => $isGAConfigured,
|
'is_ga_configured' => $isGAConfigured,
|
||||||
'is_llm_configured' => $isLLMConfigured,
|
'is_llm_configured' => $isLLMConfigured,
|
||||||
'google_client_id' => $clientId,
|
'google_client_id' => $clientId,
|
||||||
|
'google_client_secret_masked' => $maskedClientSecret,
|
||||||
|
'google_refresh_token_masked' => $maskedRefreshToken,
|
||||||
'llm_api_endpoint' => $llmEndpoint,
|
'llm_api_endpoint' => $llmEndpoint,
|
||||||
'llm_model' => $llmModel,
|
'llm_model' => $llmModel,
|
||||||
'anthropic_api_key_masked' => $maskedApiKey,
|
'anthropic_api_key_masked' => $maskedApiKey,
|
||||||
'request' => $this->request,
|
], 'blank'); // Use 'blank' rendering mode for admin pages
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
style('display:none');
|
style('analyticshub', 'admin');
|
||||||
|
script('analyticshub', 'admin');
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div id="analytics-hub-settings" class="section analytics-hub-settings">
|
<div id="analytics-hub-settings" class="section analytics-hub-settings">
|
||||||
@@ -20,8 +21,6 @@ style('display:none');
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<form id="analytics-hub-form" class="analytics-hub-settings__form">
|
<form id="analytics-hub-form" class="analytics-hub-settings__form">
|
||||||
<?php print_unescaped($l->t('CSRF Token: %s', [$_['request']->getParam('requesttoken')])); ?>
|
|
||||||
<input type="hidden" name="requesttoken" value="<?php p($_['request']->getParam('requesttoken')); ?>" />
|
|
||||||
|
|
||||||
<!-- Google Analytics Configuration -->
|
<!-- Google Analytics Configuration -->
|
||||||
<div class="analytics-hub-settings__section">
|
<div class="analytics-hub-settings__section">
|
||||||
|
|||||||
Reference in New Issue
Block a user