Commit 7920ceac authored by Stefan Galinski's avatar Stefan Galinski 🎮

[TASK] Heavy optimizations

parent f17c7b9b
......@@ -27,7 +27,6 @@ namespace TYPO3\Languagevisibility\Element;
***************************************************************/
use ReflectionClass;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Utility\GeneralUtility;
......
......@@ -55,9 +55,9 @@ class MenuHook implements AbstractMenuFilterPagesHookInterface {
GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('language', 'id'))
) {
return FALSE;
} else {
return TRUE;
}
return TRUE;
}
/**
......
......@@ -69,6 +69,9 @@ class PageHook implements PageRepositoryGetPageOverlayHookInterface, PageReposit
return;
}
$pageInputIsArray = is_array($pageInput);
$languageUid = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('language', 'id');
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
$row = $queryBuilder->select('*')
......@@ -78,24 +81,19 @@ class PageHook implements PageRepositoryGetPageOverlayHookInterface, PageReposit
)
->setMaxResults(1)
->execute()->fetch();
if (!is_array($row)) {
return;
}
$pageInputIsArray = is_array($pageInput);
$languageUid = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('language', 'id');
if ($languageUid >= 0 && !FrontendServices::checkVisiblityForElement($row, 'pages', $languageUid)
&& $pageInputIsArray
) {
$pageInput['_NOTVISIBLE'] = TRUE;
if ($languageUid >= 0 && !FrontendServices::checkVisiblityForElement($row, 'pages', $languageUid)) {
if ($pageInputIsArray) {
$pageInput['_NOTVISIBLE'] = TRUE;
}
return;
}
// call service to know if element is visible and which overlay language to use
$overlayLanguage = FrontendServices::getOverlayLanguageIdForElementRecord($row, 'pages', $lUid);
if ($overlayLanguage === FALSE) {
if ($pageInputIsArray) {
$pageInput['_NOTVISIBLE'] = TRUE;
......@@ -118,7 +116,8 @@ class PageHook implements PageRepositoryGetPageOverlayHookInterface, PageReposit
* @param PageRepository $parent
* @return void
*/
public function getRecordOverlay_preProcess($table, &$row, &$sys_language_content, $OLmode, PageRepository $parent) {
public function getRecordOverlay_preProcess($table, &$row, &$sys_language_content, $OLmode, PageRepository $parent
) {
if (!FrontendServices::isSupportedTable($table)
|| (!is_array($row))
|| (!isset($row['uid']))) {
......@@ -138,12 +137,11 @@ class PageHook implements PageRepositoryGetPageOverlayHookInterface, PageReposit
try {
$element = FrontendServices::getElement($row, $table);
$overlayLanguage = FrontendServices::getOverlayLanguageIdForElement($element, $sys_language_content);
} catch ( InvalidRowException $e ) {
} catch (InvalidRowException $e) {
$row['uid'] = 0;
$row['pid'] = 0;
return;
}
catch (\Exception $e) {
} catch (\Exception $e) {
return;
}
......@@ -152,8 +150,8 @@ class PageHook implements PageRepositoryGetPageOverlayHookInterface, PageReposit
$row['pid'] = 0;
return;
} elseif (!$element->isMonolithicTranslated()) {
// for monolytic elements the tx_languagevisibility_feservices::getOverlayLanguageIdForElement return 0 to "tell" us that no overlay is required
// but since the TYPO3 Core interprets a language with id 0 to not return anything we need to leave the $sys_language_content untouched for MonolithicTranslated elements
// for monolytic elements the tx_languagevisibility_feservices::getOverlayLanguageIdForElement return 0 to "tell" us that no overlay is required
// but since the TYPO3 Core interprets a language with id 0 to not return anything we need to leave the $sys_language_content untouched for MonolithicTranslated elements
$sys_language_content = $overlayLanguage;
}
}
......@@ -167,7 +165,8 @@ class PageHook implements PageRepositoryGetPageOverlayHookInterface, PageReposit
* @param PageRepository $parent
* @return void
*/
public function getRecordOverlay_postProcess($table, &$row, &$sys_language_content, $OLmode, PageRepository $parent) {
public function getRecordOverlay_postProcess($table, &$row, &$sys_language_content, $OLmode, PageRepository $parent
) {
if (is_array($row) && $row['uid'] === 0 && $row['pid'] === 0) {
$row = FALSE;
return;
......@@ -220,8 +219,14 @@ class PageHook implements PageRepositoryGetPageOverlayHookInterface, PageReposit
->where(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($row['pid'], \PDO::PARAM_INT)),
$queryBuilder->expr()->eq($GLOBALS['TCA'][$table]['ctrl']['languageField'], $queryBuilder->createNamedParameter($languageId, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'], $queryBuilder->createNamedParameter($row['uid'], \PDO::PARAM_INT))
$queryBuilder->expr()->eq(
$GLOBALS['TCA'][$table]['ctrl']['languageField'],
$queryBuilder->createNamedParameter($languageId, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'],
$queryBuilder->createNamedParameter($row['uid'], \PDO::PARAM_INT)
)
)
)->setMaxResults(1)->execute()->fetch();
$GLOBALS['TSFE']->sys_page->versionOL($table, $olrow);
......
......@@ -27,6 +27,7 @@ namespace TYPO3\Languagevisibility\Repository;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\Languagevisibility\Element\Language;
use TYPO3\Languagevisibility\Manager\CacheManager;
......@@ -37,21 +38,14 @@ use TYPO3\Languagevisibility\Manager\CacheManager;
* @coauthor Tolleiv Nietsch <nietsch@aoemedia.de>
* @coauthor Timo Schmidt <schmidt@aoemedia.de>
*/
class LanguageRepository {
/**
* @var self
*/
protected static $instance;
class LanguageRepository implements SingletonInterface {
/**
* Internal method to fetch all language rows from the database.
*
* @see self::$allLanguageRows
* @param void
* @return void
*/
protected function fetchAllLanguageRows() {
protected function fetchAllLanguageRows(): void {
$cacheManager = CacheManager::getInstance();
$cacheData = $cacheManager->get('allLanguageRows');
......@@ -74,7 +68,7 @@ class LanguageRepository {
*
* @return array
*/
protected function getCachedOrUncacheResults() {
protected function getCachedOrUncacheResults(): array {
$cacheManager = CacheManager::getInstance();
$isCacheEnabled = Cachemanager::isCacheEnabled();
......@@ -94,7 +88,6 @@ class LanguageRepository {
/**
* This method returns an array with all available language objects in the system.
*
* @see tx_languagevisibility_language
* @return array
*/
public function getLanguages() {
......@@ -186,18 +179,4 @@ class LanguageRepository {
}
return $cacheData[$id];
}
/**
* returns an instance of the language repository as singleton.
*
* @param void
* @return LanguageRepository
*/
public static function makeInstance() {
if (! self::$instance instanceof self) {
self::$instance = GeneralUtility::makeInstance(__CLASS__);
}
return self::$instance;
}
}
......@@ -25,30 +25,27 @@ namespace TYPO3\Languagevisibility\Repository;
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\Languagevisibility\Manager\CacheManager;
use TYPO3\CMS\Backend\Utility\BackendUtility;
/**
* @author Fabio Stegmeyer <fabio.stegmeyer@sgalinski.de>
*/
class VisibilityFlagRepository {
const DB_TABLE = 'tx_languagevisibility_visibility_flag';
class VisibilityFlagRepository implements SingletonInterface {
/**
* @var self
* @var array|NULL
*/
protected static $instance;
protected $cachedFlags;
/**
* Inserts or updates a flag for a given element
*
* @param $flag string
* @param $table string
* @param $recordUid int
* @param $lUid int
* @param string $flag
* @param string $table
* @param int $recordUid
* @param int $lUid
* @return void
*/
public function setVisibilityFlag($flag, $table, $recordUid, $lUid): void {
......@@ -56,9 +53,10 @@ class VisibilityFlagRepository {
$existingVisibilityFlag = $this->getVisibilityFlag($table, $recordUid, $lUid);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
self::DB_TABLE
'tx_languagevisibility_visibility_flag'
);
$pid = 0;
if ($table === 'pages') {
$pid = $recordUid;
} else {
......@@ -74,7 +72,7 @@ class VisibilityFlagRepository {
$uid = (int) $existingVisibilityFlag['uid'];
$queryBuilder
->update(self::DB_TABLE)
->update('tx_languagevisibility_visibility_flag')
->where($queryBuilder->expr()->eq('uid', $uid))
->set('flag', $flag)
->execute();
......@@ -82,7 +80,7 @@ class VisibilityFlagRepository {
} else {
//flag doesnt exist and needs to be created
$queryBuilder
->insert(self::DB_TABLE)
->insert('tx_languagevisibility_visibility_flag')
->values(
[
'pid' => $pid,
......@@ -106,109 +104,49 @@ class VisibilityFlagRepository {
*/
public function moveVisibilityFlag($uid, $destPid): void {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
self::DB_TABLE
'tx_languagevisibility_visibility_flag'
);
$queryBuilder
->update(self::DB_TABLE)
->update('tx_languagevisibility_visibility_flag')
->where($queryBuilder->expr()->eq('uid', $uid))
->set('pid', $destPid)
->execute();
}
/**
* Returns a complete flag row or NULL if none is found
*
* @param $table
* @param $recordUid
* @param $lUid
* @return array|null
*/
public function getVisibilityFlag($table, $recordUid, $lUid): ?array {
$cacheManager = CacheManager::getInstance();
$cacheData = $cacheManager->get('visibilityFlagRowCache');
$isCacheEnabled = CacheManager::isCacheEnabled();
$cacheKey = $table . '_' . $recordUid . '_' . $lUid;
if (!$isCacheEnabled || !isset($cacheData[$cacheKey])) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
self::DB_TABLE
);
$row = $queryBuilder->select('*')
->from(self::DB_TABLE)
->where(
$queryBuilder->expr()->eq(
'record_uid', $queryBuilder->createNamedParameter($table . '_' . $recordUid, \PDO::PARAM_STR)
)
)
->andWhere(
$queryBuilder->expr()->eq(
'record_table', $queryBuilder->createNamedParameter($table, \PDO::PARAM_STR)
)
)
->andWhere(
$queryBuilder->expr()->eq(
'record_language_uid', $queryBuilder->createNamedParameter($lUid, \PDO::PARAM_INT)
)
)
->execute()->fetch();
if ($row === FALSE) {
return NULL;
}
$cacheData[$cacheKey] = $row;
$cacheManager->set('visibilityFlagRowCache', $cacheData);
}
return $cacheData[$cacheKey];
}
/**
* Return the visibility flag
*
* @param string $table
* @param int $recordUid
* @param int $lid
* @return string
* @param int $languageUid
* @return array|NULL
* @throws \Doctrine\DBAL\DBALException
*/
public function preFetchVisibilityFlagDirectlyFromDatabase($table, $recordUid, $lid): string {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::DB_TABLE);
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
public function getVisibilityFlag($table, $recordUid, $languageUid): ?array {
if ($this->cachedFlags === NULL) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_languagevisibility_visibility_flag');
$results = $queryBuilder->prepare(
'SELECT *, CONCAT_WS("-", record_table, record_language_uid, record_uid)
as hash FROM tx_languagevisibility_visibility_flag'
);
$result = $queryBuilder
->select('flag')
->from(self::DB_TABLE)
->where(
$queryBuilder->expr()->eq(
'record_table', $queryBuilder->createNamedParameter($table, \PDO::PARAM_STR)
)
)
->andWhere(
$queryBuilder->expr()->eq(
'record_language_uid', $queryBuilder->createNamedParameter($lid, \PDO::PARAM_INT)
)
)
->andWhere(
$queryBuilder->expr()->eq(
'record_uid', $queryBuilder->createNamedParameter($table . '_' . $recordUid, \PDO::PARAM_STR)
)
)
->setMaxResults(1)
->execute()->fetch();
$this->cachedFlags = [];
if ($results->execute()) {
foreach ($results->fetchAll() as $entry) {
$this->cachedFlags[$entry['hash']] = $entry;
}
}
}
if ($result !== NULL && isset($result['flag'])) {
return $result['flag'];
$flagEntry = NULL;
$cacheKey = $table . '-' . $languageUid . '-' . $table . '_' . $recordUid;
if (isset($this->cachedFlags[$cacheKey])) {
$flagEntry = $this->cachedFlags[$cacheKey];
}
return '';
return $flagEntry;
}
/**
......@@ -221,11 +159,11 @@ class VisibilityFlagRepository {
public function removeFlagsByTableAndPid($table, $pid): void {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
self::DB_TABLE
'tx_languagevisibility_visibility_flag'
);
$queryBuilder
->delete(self::DB_TABLE)
->delete('tx_languagevisibility_visibility_flag')
->where(
$queryBuilder->expr()->eq(
'pid', $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)
......@@ -245,10 +183,12 @@ class VisibilityFlagRepository {
* @return void
*/
public function deleteDefaultFlags(): void {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::DB_TABLE);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'tx_languagevisibility_visibility_flag'
);
$queryBuilder
->delete(self::DB_TABLE)
->delete('tx_languagevisibility_visibility_flag')
->where(
$queryBuilder->expr()->eq('flag', $queryBuilder->createNamedParameter('-'))
)
......
......@@ -25,16 +25,19 @@ namespace TYPO3\Languagevisibility\Service;
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Class AbstractServices
*
* @package TYPO3\Languagevisibility\Service
*/
abstract class AbstractServices {
/**
* Method to check if records of a given table support the language-visibility feature.
*
* @param string $table
* @param string $table
* @return boolean
*/
public static function isSupportedTable($table) {
$tableSupportStatus = in_array($table, VisibilityService::getSupportedTables(), TRUE);
return $tableSupportStatus;
return in_array($table, VisibilityService::getSupportedTables(), TRUE);
}
}
......@@ -35,18 +35,13 @@ use TYPO3\Languagevisibility\Utility\ExtensionUtility;
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
class BackendServices extends AbstractServices {
/**
* @var array
*/
protected static $cache_canBeUserCopyDelete = [];
/**
* @var array
*/
protected static $visibleFlagsCache = [];
/**
* Class BackendServices
*
* @package TYPO3\Languagevisibility\Service
*/
class BackendServices extends AbstractServices {
/**
* @var array
*/
......@@ -67,7 +62,7 @@ class BackendServices extends AbstractServices {
$cacheKey = sprintf('%s:%d:%d', $table, $row['uid'], $languageUid);
if (!isset(self::$cache_isVisible[$cacheKey])) {
$rep = LanguageRepository::makeInstance();
$rep = GeneralUtility::makeInstance(LanguageRepository::class);
$language = $rep->getLanguageById($languageUid);
if (!$language instanceof Language) {
return FALSE;
......@@ -341,39 +336,4 @@ class BackendServices extends AbstractServices {
return $select;
}
/**
* This method is used to create an visibility array with the default settings
* for all languages.
*
* @return array
*/
public static function getDefaultVisibilityArray(): array {
/* @var $languageRep LanguageRepository */
$languageRep = GeneralUtility::makeInstance(LanguageRepository::class);
$languageList = $languageRep->getLanguages();
$default = [];
foreach ($languageList as $language) {
/** @var Language $language */
$options = array_keys(self::getAvailableOptionsForLanguage($language));
$default[$language->getUid()] = array_shift($options);
}
return $default;
}
/**
* This method is used to get the table where original elements of the
* given table are stored.
*
* @param string $table
* @return string
*/
public static function getOriginalTableOfTranslation(string $table): string {
$translationTable = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerTable'];
if (!empty($translationTable)) {
return $translationTable;
}
return $table;
}
}
......@@ -25,24 +25,21 @@ namespace TYPO3\Languagevisibility\Service;
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use ReflectionClass;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\Languagevisibility\Element\Element;
use TYPO3\Languagevisibility\Element\ElementFactory;
use TYPO3\Languagevisibility\Element\Language;
use TYPO3\Languagevisibility\Repository\LanguageRepository;
use TYPO3\Languagevisibility\Repository\VisibilityFlagRepository;
use UnexpectedValueException;
/**
* exceptions are not handled here.
* This class just provides simple services and uses the domainmodel in classes directory!
* Class FrontendServices
*
* Methods can be used uninstanciated
* @package TYPO3\Languagevisibility\Service
*/
class FrontendServices extends AbstractServices {
class FrontendServices extends AbstractServices implements SingletonInterface {
/**
* The cache frontend
*
......@@ -51,22 +48,9 @@ class FrontendServices extends AbstractServices {
protected static $cache;
/**
* @param array $row
* @param string $table
* @param int $lUid
* @return mixed
* @var VisibilityFlagRepository|NULL $visibilityFlagRepository
*/
public static function getFallbackOrderForElement(array $row, string $table, int $lUid) {
$elementfactory = GeneralUtility::makeInstance(ElementFactory::class);
$element = $elementfactory->getElementForTable($table, $row);
$languageRep = GeneralUtility::makeInstance(LanguageRepository::class);
$language = $languageRep->getLanguageById($lUid);
if (!$language instanceof Language) {
return FALSE;
}
return $language->getFallbackOrderElement($element);
}
protected static $visibilityFlagRepository;
/**
* @param array $row
......@@ -76,13 +60,15 @@ class FrontendServices extends AbstractServices {
* @throws \Exception
*/
public static function checkVisiblityForElement(array $row, string $table, int $lUid): bool {
if (!self::$visibilityFlagRepository) {
self::$visibilityFlagRepository = GeneralUtility::makeInstance(VisibilityFlagRepository::class);
}
$visibilityFlag = self::$visibilityFlagRepository->getVisibilityFlag($table, $row['uid'], $lUid);
if ($visibilityFlag) {
$visibilityFlag = $visibilityFlag['flag'];
}
$visibilityFlagRepository = GeneralUtility::makeInstance(VisibilityFlagRepository::class);
$visibilityFlag = $visibilityFlagRepository->preFetchVisibilityFlagDirectlyFromDatabase(
$table, $row['uid'], $lUid
);
if ($visibilityFlag === '' || $visibilityFlag === '-') {
if (!$visibilityFlag || $visibilityFlag === 'yes' || $visibilityFlag === '-') {
return TRUE;
}
......@@ -107,7 +93,6 @@ class FrontendServices extends AbstractServices {
* @param array $row
* @param string $table
* @return Element
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public static function getElement(array $row, string $table) {
$elementfactory = GeneralUtility::makeInstance(ElementFactory::class);
......@@ -127,7 +112,7 @@ class FrontendServices extends AbstractServices {
return FALSE;
}
/** @var $visibility VisibilityService */
/** @var VisibilityService $visibility */
$visibility = GeneralUtility::makeInstance(VisibilityService::class);
return $visibility->getOverlayLanguageIdForLanguageAndElement($language, $element);
}
......@@ -141,59 +126,28 @@ class FrontendServices extends AbstractServices {
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public static function getOverlayLanguageIdForElementRecord(array $row, string $table, int $lUid) {
$reflect = new ReflectionClass(__CLASS__);
$cacheKey = implode('_', [$reflect->getShortName(), __FUNCTION__, $row['uid'], $table, $lUid]);
if (self::getCache()->has($cacheKey)) {
return self::getCache()->get($cacheKey);
if (!self::$cache) {
self::$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('tx_languagevisibility');
}
$cacheKey = implode('_', [str_replace('\\', '_', __CLASS__), __FUNCTION__, $row['uid'], $table, $lUid]);
if (self::$cache->has($cacheKey)) {
return self::$cache->get($cacheKey);
}
$elementfactory = GeneralUtility::makeInstance(ElementFactory::class);
$element = $elementfactory->getElementForTable($table, $row);
$languageRep = GeneralUtility::makeInstance(LanguageRepository::class);
$language = $languageRep->getLanguageById($lUid);
if (!$language instanceof Language) {
return 0;
}
$elementfactory = GeneralUtility::makeInstance(ElementFactory::class);
$element = $elementfactory->getElementForTable($table, $row);
/** @var VisibilityService $visibilityService */
$visibilityService = GeneralUtility::makeInstance(VisibilityService::class);
$overlayLanguageId = $visibilityService->getOverlayLanguageIdForLanguageAndElement($language, $element);
self::getCache()->set($cacheKey, $overlayLanguageId);
self::$cache->set($cacheKey, $overlayLanguageId);
return $overlayLanguageId;
}
/**
* @param $uid
* @param $table
* @param $lUid
* @return mixed
* @throws \Exception
*/
public static function getOverlayLanguageIdForElementRecordForced($uid, $table, $lUid) {
$elementfactory = GeneralUtility::makeInstance(ElementFactory::class);
$element = $elementfactory->getElementForTable($table, $uid);
$languageRep = GeneralUtility::makeInstance(LanguageRepository::class);
$language = $languageRep->getLanguageById($lUid);
if (!$language instanceof Language) {
return 0;
}
$visibility = GeneralUtility::makeInstance(VisibilityService::class);
$visibility->isVisible($language, $element);
return $visibility->getLastRelevantOverlayLanguageId();
}
/**
* Gets the cache frontend for tx_languagevisibility
*
* @return \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public static function getCache() {
if (!self::$cache) {
self::$cache = GeneralUtility::makeInstance(CacheManager::class)
->getCache('tx_languagevisibility');
}
return self::$cache;
}
}
......@@ -105,17 +105,6 @@ class VisibilityService implements SingletonInterface {