Skip to content

Conversation

@TDannhauer
Copy link
Contributor

Guard to avoid double declaration. root cause still unclear.

Guard to avoid double declaration. rootcause still unclear.
@TDannhauer TDannhauer requested review from Copilot and ralflang August 7, 2025 20:51
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a guard to prevent the redeclaration of the Kronolith_Application class in case the file gets included multiple times through different autoloaders or paths.

  • Adds a class existence check before class definition
  • Includes explanatory comment about the purpose of the guard
  • Uses early return to prevent redeclaration errors

if (class_exists('Kronolith_Application', false)) {
return;
}

Copy link

Copilot AI Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider using include_once or require_once at the inclusion point instead of adding guards within the file. This approach is more conventional and prevents the file from being processed multiple times entirely.

Suggested change

Copilot uses AI. Check for mistakes.
if (class_exists('Kronolith_Application', false)) {
return;
}

Copy link

Copilot AI Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guard addresses a symptom rather than the root cause. Since the description mentions the root cause is unclear, consider investigating why the file is being included multiple times to implement a more robust solution.

Suggested change

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rather fix the portal block loader.

@amulet1
Copy link
Contributor

amulet1 commented Aug 8, 2025

It looks like the root cause of this is when $registry->getInitialPage() is called without $app parameter.

For example, it happens when 'horde/services/portal/' url is opened.

Then getInitialPage() calls callAppMethod() which then calls getApiInstance(null, 'Application'). This results in $classname = '_Application'. The attempt to autoload _Application class in class_exists($classname, true) call instead of Kronolith_Application (which is already loaded at this stage) fails, and it then loads kronolith/lib/Application.php using include_once $path which results in a double declaration:

        // Implied attempt to trigger a previously setup autoloader
        if (class_exists($classname, true)) {
        } elseif (file_exists($path)) {
            include_once $path;
        } else {
            $classname = __CLASS__ . '_' . $cname;
        }

The solution is to set $app if it is null by doing something like this at the beginning of getApiInstance() (and probably in callAppMethod() too):

        if (is_null($app)) {
            $app = $this->getApp();
        }

Then there will be no need to add the guard. I can submit a PR with additional cleanups, if needed.

Note, there is also another (unrelated) case of double declaration, when class is loaded using loadConfigFile() (for example, in case of hooks.php). See this for my original (wrong) attempt to fix it. The right solution would be not to use loadConfigFile() to load hooks.php (or any other possible case when there is a class definition inside of the file).

amulet1 added a commit to amulet1/horde_core that referenced this pull request Aug 11, 2025
This fixes double declaration issues such as decribed in horde/kronolith#17
@amulet1
Copy link
Contributor

amulet1 commented Aug 11, 2025

I added a minimal Horde Core fix that resolves the issue.

Potentially other Horde_Registry methods should have the same check added.
Also, the check might need to be made consistent (some methods use is_null, others ise empty).

I would bee happy to update it, if requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants