<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

if (!class_exists('ViisonCommon_Plugin_BootstrapV12')) {
    require_once('PluginBootstrapV12.php');
}

/**
 * Version 13 of the common plugin Bootstrap class. This version is based on ViisonCommon_Plugin_BootstrapV12,
 * but additionally adds a custom class loader (exactly once), that ensures that the proxy class of
 * Shopware\Models\Shop\Locale can be loaded. This is necessary to always allow deserialization of backend sessions,
 * even if they contain a serialized locale proxy instace.
 * Additionally this version also fixes {@link self::getLabel()} and {@link self::getLocalizedPluginDescription()} so
 * that they are always executed.
 *
 * This class needs to be manually loaded in the respective plugin via:
 *
 * if (!class_exists('ViisonCommon_Plugin_BootstrapV13')) {
 *     require_once('ViisonCommon/PluginBootstrapV13.php');
 * }
 */
abstract class ViisonCommon_Plugin_BootstrapV13 extends ViisonCommon_Plugin_BootstrapV12
{
    /**
     * {@inheritdoc}
     *
     * Overrides the parent implementation to remove the check for the 'Util' class, which has never been necessary in
     * the first place.
     */
    public function getLabel()
    {
        $pluginInfo = $this->getPluginInfo();
        $language = static::getDefaultShopLanguage();
        if (isset($pluginInfo['label'][$language])) {
            return $pluginInfo['label'][$language];
        } elseif (isset($pluginInfo['label']['en'])) {
            return $pluginInfo['label']['en'];
        } else {
            return parent::getLabel();
        }
    }

    /**
     * {@inheritdoc}
     *
     * Overrides the parent implementation to remove the check for the 'Util' class, which has never been necessary in
     * the first place.
     */
    public function getLocalizedPluginDescription()
    {
        // Try to find description in default language
        $language = static::getDefaultShopLanguage();
        $defaultLanguageDescriptionPath = sprintf('%sdescription.%s.html', $this->Path(), $language);
        if (is_readable($defaultLanguageDescriptionPath)) {
            return file_get_contents($defaultLanguageDescriptionPath);
        }

        // Try to find an english description as fallback
        $englishDescriptionPath = sprintf('%sdescription.en.html', $this->Path());
        if (is_readable($englishDescriptionPath)) {
            return file_get_contents($englishDescriptionPath);
        }

        return null;
    }

    /**
     * The proxy class name of the 'Shopware\Models\Shop\Locale' class. Don't access this variable directly, but use
     * {@link self::getLocaleProxyClassName()} instead.
     *
     * @var string|null
     */
    protected static $localeProxyClassName = null;

    /**
     * @return string The proxy class name of the 'Shopware\Models\Shop\Locale' class.
     */
    public static function getLocaleProxyClassName()
    {
        if (!static::$localeProxyClassName) {
            $proxyNamespace = Shopware()->Container()->getParameter(
                'shopware.model.proxyNamespace',
                '\\Shopware\\Proxies'
            );
            static::$localeProxyClassName = ltrim(($proxyNamespace . '\\__CG__\\Shopware\\Models\\Shop\\Locale'), '\\');
        }

        return static::$localeProxyClassName;
    }
}

// Add a new class loader that can load only the proxy class for 'Shopware\Models\Shop\Locale' exactly once. If the
// respective proxy class does not exist, it is generated using Doctrine's entity manager.
if (!defined('DONT_REGISTER_VIISON_SESSION_BUG_WORKAROUND_AUTOLOADER_20180808')) {
    spl_autoload_register(function ($className) {
        // Make sure that this loader only loads the locale proxy class
        $localeProxyClassName = ViisonCommon_Plugin_BootstrapV13::getLocaleProxyClassName();
        if ($className !== $localeProxyClassName) {
            return;
        }

        if (class_exists($localeProxyClassName, false)) {
            // Should not happen
            return;
        }

        // Check that the model proxy directory is configured
        $proxyDir = Shopware()->Container()->getParameter('shopware.model.proxyDir');
        if (empty($proxyDir)) {
            // Should not happen
            return;
        }

        // Check whether the proxy class can be loaded
        $proxyFileName = $proxyDir . DIRECTORY_SEPARATOR . '__CG__ShopwareModelsShopLocale.php';
        if (!is_readable($proxyFileName)) {
            // The proxy class does not exist in the cache yet, hence we have to create it ourselves
            $entityManager = Shopware()->Container()->get('models');
            $localeModelClass = 'Shopware\\Models\\Shop\\Locale';
            try {
                $pseudoLocale = $entityManager->getReference($localeModelClass, -1);
                $entityManager->detach($pseudoLocale);
            } catch (\Exception $e) {
                // Try to log the error
                $pluginLogger = Shopware()->Container()->get('pluginlogger');
                if ($pluginLogger) {
                    $pluginLogger->error(
                        sprintf('Failed to generate proxy class for model "%s".', $localeModelClass),
                        ['exception' => $e]
                    );
                }
            }
        }

        // phpcs:ignore Generic.PHP.NoSilencedErrors
        @include_once $proxyFileName;
    });

    define('DONT_REGISTER_VIISON_SESSION_BUG_WORKAROUND_AUTOLOADER_20180808', true);
}
