Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1125182
cache_manager.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Sep 4, 6:31 AM
Size
23 KB
Mime Type
text/x-php
Expires
Sat, Sep 6, 6:31 AM (1 h, 2 m)
Engine
blob
Format
Raw Data
Handle
727833
Attached To
rINP In-Portal
cache_manager.php
View Options
<?php
/**
* @version $Id: cache_manager.php 16432 2016-11-18 09:30:26Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2011 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined
(
'FULL_PATH'
)
or
die
(
'restricted access!'
);
class
kCacheManager
extends
kBase
implements
kiCacheable
{
/**
* Used variables from SystemSettings table
*
* @var Array
* @access protected
*/
protected
$configVariables
=
Array
();
/**
* Used variables from SystemSettings table retrieved from unit cache
*
* @var Array
* @access protected
*/
protected
$originalConfigVariables
=
Array
();
/**
* IDs of config variables used in current run (for caching)
*
* @var Array
* @access protected
*/
protected
$configIDs
=
Array
();
/**
* IDs of config variables retrieved from unit cache
*
* @var Array
* @access protected
*/
protected
$originalConfigIDs
=
Array
();
/**
* Object of memory caching class
*
* @var kCache
* @access protected
*/
protected
$cacheHandler
=
null
;
protected
$temporaryCache
=
Array
(
'registerAggregateTag'
=>
Array
(),
'registerScheduledTask'
=>
Array
(),
'registerHook'
=>
Array
(),
'registerBuildEvent'
=>
Array
(),
'registerAggregateTag'
=>
Array
(),
);
/**
* Name of database table, where configuration settings are stored
*
* @var string
* @access protected
*/
protected
$settingTableName
=
''
;
/**
* Set's references to kApplication and DBConnection interface class instances
*
* @access public
*/
public
function
__construct
()
{
parent
::
__construct
();
$this
->
settingTableName
=
TABLE_PREFIX
.
'SystemSettings'
;
if
(
defined
(
'IS_INSTALL'
)
&&
IS_INSTALL
)
{
// table substitution required, so "root" can perform login to upgrade to 5.2.0, where setting table was renamed
if
(
!
$this
->
Application
->
TableFound
(
TABLE_PREFIX
.
'SystemSettings'
)
)
{
$this
->
settingTableName
=
TABLE_PREFIX
.
'ConfigurationValues'
;
}
}
}
/**
* Creates caching manager instance
*
* @access public
*/
public
function
InitCache
()
{
$this
->
cacheHandler
=
$this
->
Application
->
makeClass
(
'kCache'
);
}
/**
* Returns cache key, used to cache phrase and configuration variable IDs used on current page
*
* @return string
* @access protected
*/
protected
function
getCacheKey
()
{
// TODO: maybe language part isn't required, since same phrase from different languages have one ID now
return
$this
->
Application
->
GetVar
(
't'
)
.
$this
->
Application
->
GetVar
(
'm_theme'
)
.
$this
->
Application
->
GetVar
(
'm_lang'
)
.
$this
->
Application
->
isAdmin
;
}
/**
* Loads phrases and configuration variables, that were used on this template last time
*
* @access public
*/
public
function
LoadApplicationCache
()
{
$phrase_ids
=
$config_ids
=
Array
();
$sql
=
'SELECT PhraseList, ConfigVariables
FROM '
.
TABLE_PREFIX
.
'PhraseCache
WHERE Template = '
.
$this
->
Conn
->
qstr
(
md5
(
$this
->
getCacheKey
())
);
$res
=
$this
->
Conn
->
GetRow
(
$sql
);
if
(
$res
)
{
if
(
$res
[
'PhraseList'
]
)
{
$phrase_ids
=
explode
(
','
,
$res
[
'PhraseList'
]);
}
if
(
$res
[
'ConfigVariables'
]
)
{
$config_ids
=
array_diff
(
explode
(
','
,
$res
[
'ConfigVariables'
]),
$this
->
originalConfigIDs
);
}
}
$this
->
Application
->
Phrases
->
Init
(
'phrases'
,
''
,
null
,
$phrase_ids
);
$this
->
configIDs
=
$this
->
originalConfigIDs
=
$config_ids
;
$this
->
InitConfig
();
}
/**
* Updates phrases and configuration variables, that were used on this template
*
* @access public
*/
public
function
UpdateApplicationCache
()
{
$update
=
false
;
//something changed
$update
=
$update
||
$this
->
Application
->
Phrases
->
NeedsCacheUpdate
();
$update
=
$update
||
(
count
(
$this
->
configIDs
)
&&
$this
->
configIDs
!=
$this
->
originalConfigIDs
);
if
(
$update
)
{
$fields_hash
=
Array
(
'PhraseList'
=>
implode
(
','
,
$this
->
Application
->
Phrases
->
Ids
),
'CacheDate'
=>
adodb_mktime
(),
'Template'
=>
md5
(
$this
->
getCacheKey
()
),
'ConfigVariables'
=>
implode
(
','
,
array_unique
(
$this
->
configIDs
)),
);
$this
->
Conn
->
doInsert
(
$fields_hash
,
TABLE_PREFIX
.
'PhraseCache'
,
'REPLACE'
);
}
}
/**
* Loads configuration variables, that were used on this template last time
*
* @access protected
*/
protected
function
InitConfig
()
{
if
(!
$this
->
originalConfigIDs
)
{
return
;
}
$sql
=
'SELECT VariableValue, VariableName
FROM '
.
$this
->
settingTableName
.
'
WHERE VariableId IN ('
.
implode
(
','
,
$this
->
originalConfigIDs
)
.
')'
;
$config_variables
=
$this
->
Conn
->
GetCol
(
$sql
,
'VariableName'
);
$this
->
configVariables
=
array_merge
(
$this
->
configVariables
,
$config_variables
);
}
/**
* Returns configuration option value by name
*
* @param string $name
* @return string
* @access public
*/
public
function
ConfigValue
(
$name
)
{
$site_domain_override
=
Array
(
'DefaultEmailSender'
=>
'AdminEmail'
,
'DefaultEmailRecipients'
=>
'DefaultEmailRecipients'
,
);
if
(
isset
(
$site_domain_override
[
$name
])
)
{
$res
=
$this
->
Application
->
siteDomainField
(
$site_domain_override
[
$name
]);
if
(
$res
)
{
return
$res
;
}
}
if
(
array_key_exists
(
$name
,
$this
->
configVariables
)
)
{
return
$this
->
configVariables
[
$name
];
}
if
(
defined
(
'IS_INSTALL'
)
&&
IS_INSTALL
&&
!
$this
->
Application
->
TableFound
(
$this
->
settingTableName
,
true
)
)
{
return
false
;
}
$this
->
Conn
->
nextQueryCachable
=
true
;
$sql
=
'SELECT VariableId, VariableValue
FROM '
.
$this
->
settingTableName
.
'
WHERE VariableName = '
.
$this
->
Conn
->
qstr
(
$name
);
$res
=
$this
->
Conn
->
GetRow
(
$sql
);
if
(
$res
!==
false
)
{
$this
->
configIDs
[]
=
$res
[
'VariableId'
];
$this
->
configVariables
[
$name
]
=
$res
[
'VariableValue'
];
return
$res
[
'VariableValue'
];
}
trigger_error
(
'Usage of undefined configuration variable "<strong>'
.
$name
.
'</strong>"'
,
E_USER_NOTICE
);
return
false
;
}
/**
* Changes value of individual configuration variable (+resets cache, when needed)
*
* @param string $name
* @param string $value
* @param bool $local_cache_only
* @return string
* @access public
*/
public
function
SetConfigValue
(
$name
,
$value
,
$local_cache_only
=
false
)
{
$this
->
configVariables
[
$name
]
=
$value
;
if
(
$local_cache_only
)
{
return
;
}
$fields_hash
=
Array
(
'VariableValue'
=>
$value
);
$this
->
Conn
->
doUpdate
(
$fields_hash
,
$this
->
settingTableName
,
'VariableName = '
.
$this
->
Conn
->
qstr
(
$name
));
if
(
array_key_exists
(
$name
,
$this
->
originalConfigVariables
)
&&
$value
!=
$this
->
originalConfigVariables
[
$name
]
)
{
$this
->
DeleteUnitCache
();
}
}
/**
* Loads data, that was cached during unit config parsing
*
* @return bool
* @access public
*/
public
function
LoadUnitCache
()
{
if
(
$this
->
Application
->
isCachingType
(
CACHING_TYPE_MEMORY
)
)
{
$data
=
$this
->
Application
->
getCache
(
'master:configs_parsed'
,
false
,
CacheSettings
::
$unitCacheRebuildTime
);
}
else
{
$data
=
$this
->
Application
->
getDBCache
(
'configs_parsed'
,
CacheSettings
::
$unitCacheRebuildTime
);
}
if
(
$data
)
{
$cache
=
unserialize
(
$data
);
// 126 KB all modules
unset
(
$data
);
$this
->
Application
->
InitManagers
();
$this
->
Application
->
setFromCache
(
$cache
);
$aggregator
=
$this
->
Application
->
recallObject
(
'TagsAggregator'
,
'kArray'
);
/* @var $aggregator kArray */
$aggregator
->
setFromCache
(
$cache
);
$this
->
setFromCache
(
$cache
);
unset
(
$cache
);
return
true
;
}
return
false
;
}
/**
* Empties factory and event manager cache (without storing changes)
*/
public
function
EmptyUnitCache
()
{
// maybe discover keys automatically from corresponding classes
$cache_keys
=
Array
(
'Factory.Files'
,
'Factory.realClasses'
,
'ConfigReader.prefixFiles'
,
'EventManager.beforeHooks'
,
'EventManager.afterHooks'
,
'EventManager.scheduledTasks'
,
'EventManager.buildEvents'
,
'Application.ReplacementTemplates'
,
'Application.RewriteListeners'
,
'Application.ModuleInfo'
,
'Application.ConfigHash'
,
'Application.ConfigCacheIds'
,
);
$empty_cache
=
Array
();
foreach
(
$cache_keys
as
$cache_key
)
{
$empty_cache
[
$cache_key
]
=
Array
();
}
$this
->
Application
->
setFromCache
(
$empty_cache
);
$this
->
setFromCache
(
$empty_cache
);
// otherwise ModulesHelper indirectly used from includeConfigFiles won't work
$this
->
Application
->
RegisterDefaultClasses
();
$this
->
Application
->
RegisterDefaultBuildEvents
();
}
/**
* Updates data, that was parsed from unit configs this time
*
* @access public
*/
public
function
UpdateUnitCache
()
{
$aggregator
=
$this
->
Application
->
recallObject
(
'TagsAggregator'
,
'kArray'
);
/* @var $aggregator kArray */
$this
->
preloadConfigVars
();
// preloading will put to cache
$cache
=
array_merge
(
$this
->
Application
->
getToCache
(),
$aggregator
->
getToCache
(),
$this
->
getToCache
()
);
$cache_rebuild_by
=
SERVER_NAME
.
' ('
.
$this
->
Application
->
getClientIp
()
.
') - '
.
adodb_date
(
'd/m/Y H:i:s'
);
if
(
$this
->
Application
->
isCachingType
(
CACHING_TYPE_MEMORY
))
{
$this
->
Application
->
setCache
(
'master:configs_parsed'
,
serialize
(
$cache
));
$this
->
Application
->
setCache
(
'master:last_cache_rebuild'
,
$cache_rebuild_by
);
}
else
{
$this
->
Application
->
setDBCache
(
'configs_parsed'
,
serialize
(
$cache
));
$this
->
Application
->
setDBCache
(
'last_cache_rebuild'
,
$cache_rebuild_by
);
}
}
public
function
delayUnitProcessing
(
$method
,
$params
)
{
if
(
$this
->
Application
->
InitDone
)
{
// init already done -> call immediately (happens during installation)
$function
=
Array
(&
$this
->
Application
,
$method
);
call_user_func_array
(
$function
,
$params
);
return
;
}
$this
->
temporaryCache
[
$method
][]
=
$params
;
}
public
function
applyDelayedUnitProcessing
()
{
foreach
(
$this
->
temporaryCache
as
$method
=>
$method_calls
)
{
$function
=
Array
(&
$this
->
Application
,
$method
);
foreach
(
$method_calls
as
$method_call
)
{
call_user_func_array
(
$function
,
$method_call
);
}
$this
->
temporaryCache
[
$method
]
=
Array
();
}
}
/**
* Deletes all data, that was cached during unit config parsing (excluding unit config locations)
*
* @param Array $config_variables
* @access public
*/
public
function
DeleteUnitCache
(
$config_variables
=
null
)
{
if
(
isset
(
$config_variables
)
&&
!
array_intersect
(
array_keys
(
$this
->
originalConfigVariables
),
$config_variables
)
)
{
// prevent cache reset, when given config variables are not in unit cache
return
;
}
if
(
$this
->
Application
->
isCachingType
(
CACHING_TYPE_MEMORY
)
)
{
$this
->
Application
->
rebuildCache
(
'master:configs_parsed'
,
kCache
::
REBUILD_LATER
,
CacheSettings
::
$unitCacheRebuildTime
);
}
else
{
$this
->
rebuildDBCache
(
'configs_parsed'
,
kCache
::
REBUILD_LATER
,
CacheSettings
::
$unitCacheRebuildTime
);
}
}
/**
* Deletes cached section tree, used during permission checking and admin console tree display
*
* @return void
* @access public
*/
public
function
DeleteSectionCache
()
{
if
(
$this
->
Application
->
isCachingType
(
CACHING_TYPE_MEMORY
)
)
{
$this
->
Application
->
rebuildCache
(
'master:sections_parsed'
,
kCache
::
REBUILD_LATER
,
CacheSettings
::
$sectionsParsedRebuildTime
);
}
else
{
$this
->
rebuildDBCache
(
'sections_parsed'
,
kCache
::
REBUILD_LATER
,
CacheSettings
::
$sectionsParsedRebuildTime
);
}
}
/**
* Preloads 21 widely used configuration variables, so they will get to cache for sure
*
* @access protected
*/
protected
function
preloadConfigVars
()
{
$config_vars
=
Array
(
// session related
'SessionTimeout'
,
'SessionCookieName'
,
'SessionCookieDomains'
,
'SessionBrowserSignatureCheck'
,
'SessionIPAddressCheck'
,
'CookieSessions'
,
'KeepSessionOnBrowserClose'
,
'User_GuestGroup'
,
'User_LoggedInGroup'
,
'RegistrationUsernameRequired'
,
// output related
'UseModRewrite'
,
'UseContentLanguageNegotiation'
,
'UseOutputCompression'
,
'OutputCompressionLevel'
,
'Config_Site_Time'
,
'SystemTagCache'
,
'DefaultGridPerPage'
,
// tracking related
'UseChangeLog'
,
'UseVisitorTracking'
,
'ModRewriteUrlEnding'
,
'ForceModRewriteUrlEnding'
,
'RunScheduledTasksFromCron'
,
);
$escaped_config_vars
=
$this
->
Conn
->
qstrArray
(
$config_vars
);
$sql
=
'SELECT VariableId, VariableName, VariableValue
FROM '
.
$this
->
settingTableName
.
'
WHERE VariableName IN ('
.
implode
(
','
,
$escaped_config_vars
)
.
')'
;
$data
=
$this
->
Conn
->
Query
(
$sql
,
'VariableId'
);
foreach
(
$data
as
$variable_id
=>
$variable_info
)
{
$this
->
configIDs
[]
=
$variable_id
;
$this
->
configVariables
[
$variable_info
[
'VariableName'
]
]
=
$variable_info
[
'VariableValue'
];
}
}
/**
* Sets data from cache to object
*
* Used for cases, when ConfigValue is called before LoadApplicationCache method (e.g. session init, url engine init)
*
* @param Array $data
* @access public
*/
public
function
setFromCache
(&
$data
)
{
$this
->
configVariables
=
$this
->
originalConfigVariables
=
$data
[
'Application.ConfigHash'
];
$this
->
configIDs
=
$this
->
originalConfigIDs
=
$data
[
'Application.ConfigCacheIds'
];
}
/**
* Gets object data for caching
* The following caches should be reset based on admin interaction (adjusting config, enabling modules etc)
*
* @access public
* @return Array
*/
public
function
getToCache
()
{
return
Array
(
'Application.ConfigHash'
=>
$this
->
configVariables
,
'Application.ConfigCacheIds'
=>
$this
->
configIDs
,
// not in use, since it only represents template specific values, not global ones
// 'Application.Caches.ConfigVariables' => $this->originalConfigIDs,
);
}
/**
* Returns caching type (none, memory, temporary)
*
* @param int $caching_type
* @return bool
* @access public
*/
public
function
isCachingType
(
$caching_type
)
{
return
$this
->
cacheHandler
->
getCachingType
()
==
$caching_type
;
}
/**
* Returns cached $key value from cache named $cache_name
*
* @param int $key key name from cache
* @param bool $store_locally store data locally after retrieved
* @param int $max_rebuild_seconds
* @return mixed
* @access public
*/
public
function
getCache
(
$key
,
$store_locally
=
true
,
$max_rebuild_seconds
=
0
)
{
return
$this
->
cacheHandler
->
getCache
(
$key
,
$store_locally
,
$max_rebuild_seconds
);
}
/**
* Stores new $value in cache with $key name
*
* @param int $key key name to add to cache
* @param mixed $value value of cached record
* @param int $expiration when value expires (0 - doesn't expire)
* @return bool
* @access public
*/
public
function
setCache
(
$key
,
$value
,
$expiration
=
0
)
{
return
$this
->
cacheHandler
->
setCache
(
$key
,
$value
,
$expiration
);
}
/**
* Stores new $value in cache with $key name (only if not there already)
*
* @param int $key key name to add to cache
* @param mixed $value value of cached record
* @param int $expiration when value expires (0 - doesn't expire)
* @return bool
* @access public
*/
public
function
addCache
(
$key
,
$value
,
$expiration
=
0
)
{
return
$this
->
cacheHandler
->
addCache
(
$key
,
$value
,
$expiration
);
}
/**
* Sets rebuilding mode for given cache
*
* @param string $name
* @param int $mode
* @param int $max_rebuilding_time
* @return bool
* @access public
*/
public
function
rebuildCache
(
$name
,
$mode
=
null
,
$max_rebuilding_time
=
0
)
{
return
$this
->
cacheHandler
->
rebuildCache
(
$name
,
$mode
,
$max_rebuilding_time
);
}
/**
* Deletes key from cache
*
* @param string $key
* @return void
* @access public
*/
public
function
deleteCache
(
$key
)
{
$this
->
cacheHandler
->
delete
(
$key
);
}
/**
* Reset's all memory cache at once
*
* @return void
* @access public
*/
public
function
resetCache
()
{
$this
->
cacheHandler
->
reset
();
}
/**
* Returns value from database cache
*
* @param string $name key name
* @param int $max_rebuild_seconds
* @return mixed
* @access public
*/
public
function
getDBCache
(
$name
,
$max_rebuild_seconds
=
0
)
{
// no serials in cache key OR cache is outdated
$rebuilding
=
false
;
$wait_seconds
=
$max_rebuild_seconds
;
while
(
true
)
{
$cached_data
=
$this
->
_getDBCache
(
Array
(
$name
,
$name
.
'_rebuilding'
,
$name
.
'_rebuild'
));
if
(
$cached_data
[
$name
.
'_rebuild'
]
)
{
// cache rebuild requested -> rebuild now
$this
->
deleteDBCache
(
$name
.
'_rebuild'
);
if
(
$this
->
rebuildDBCache
(
$name
,
kCache
::
REBUILD_NOW
,
$max_rebuild_seconds
,
'[M1]'
)
)
{
return
false
;
}
}
$cache
=
$cached_data
[
$name
];
$rebuilding
=
$cached_data
[
$name
.
'_rebuilding'
];
if
(
(
$cache
===
false
)
&&
(!
$rebuilding
||
$wait_seconds
==
0
)
)
{
// cache missing and nobody rebuilding it -> rebuild; enough waiting for cache to be ready
$this
->
rebuildDBCache
(
$name
,
kCache
::
REBUILD_NOW
,
$max_rebuild_seconds
,
'[M2'
.
(
$rebuilding
?
'R'
:
'!R'
)
.
',WS='
.
$wait_seconds
.
']'
);
return
false
;
}
elseif
(
$cache
!==
false
)
{
// cache present -> return it
$this
->
cacheHandler
->
storeStatistics
(
$name
,
$rebuilding
?
'h'
:
'H'
);
return
$cache
;
}
$wait_seconds
-=
kCache
::
WAIT_STEP
;
sleep
(
kCache
::
WAIT_STEP
);
}
$this
->
rebuildDBCache
(
$name
,
kCache
::
REBUILD_NOW
,
$max_rebuild_seconds
,
'[M3'
.
(
$rebuilding
?
'R'
:
'!R'
)
.
',WS='
.
$wait_seconds
.
']'
);
return
false
;
}
/**
* Returns value from database cache
*
* @param string|Array $names key name
* @return mixed
* @access protected
*/
protected
function
_getDBCache
(
$names
)
{
$res
=
Array
();
$names
=
(
array
)
$names
;
$this
->
Conn
->
nextQueryCachable
=
true
;
$sql
=
'SELECT Data, Cached, LifeTime, VarName
FROM '
.
TABLE_PREFIX
.
'SystemCache
WHERE VarName IN ('
.
implode
(
','
,
$this
->
Conn
->
qstrArray
(
$names
))
.
')'
;
$cached_data
=
$this
->
Conn
->
Query
(
$sql
,
'VarName'
);
foreach
(
$names
as
$name
)
{
if
(
!
isset
(
$cached_data
[
$name
])
)
{
$res
[
$name
]
=
false
;
continue
;
}
$lifetime
=
(
int
)
$cached_data
[
$name
][
'LifeTime'
];
// in seconds
if
(
(
$lifetime
>
0
)
&&
(
$cached_data
[
$name
][
'Cached'
]
+
$lifetime
<
adodb_mktime
())
)
{
// delete expired
$this
->
Conn
->
nextQueryCachable
=
true
;
$sql
=
'DELETE FROM '
.
TABLE_PREFIX
.
'SystemCache
WHERE VarName = '
.
$this
->
Conn
->
qstr
(
$name
);
$this
->
Conn
->
Query
(
$sql
);
$res
[
$name
]
=
false
;
continue
;
}
$res
[
$name
]
=
$cached_data
[
$name
][
'Data'
];
}
return
count
(
$res
)
==
1
?
array_pop
(
$res
)
:
$res
;
}
/**
* Sets value to database cache
*
* @param string $name
* @param mixed $value
* @param int|bool $expiration
* @return void
* @access public
*/
public
function
setDBCache
(
$name
,
$value
,
$expiration
=
false
)
{
$this
->
cacheHandler
->
storeStatistics
(
$name
,
'WU'
);
$this
->
deleteDBCache
(
$name
.
'_rebuilding'
);
$this
->
_setDBCache
(
$name
,
$value
,
$expiration
);
}
/**
* Sets value to database cache
*
* @param string $name
* @param mixed $value
* @param int|bool $expiration
* @param string $insert_type
* @return bool
* @access protected
*/
protected
function
_setDBCache
(
$name
,
$value
,
$expiration
=
false
,
$insert_type
=
'REPLACE'
)
{
if
(
(
int
)
$expiration
<=
0
)
{
$expiration
=
-
1
;
}
$fields_hash
=
Array
(
'VarName'
=>
$name
,
'Data'
=>
&
$value
,
'Cached'
=>
adodb_mktime
(),
'LifeTime'
=>
(
int
)
$expiration
,
);
$this
->
Conn
->
nextQueryCachable
=
true
;
return
$this
->
Conn
->
doInsert
(
$fields_hash
,
TABLE_PREFIX
.
'SystemCache'
,
$insert_type
);
}
/**
* Sets value to database cache
*
* @param string $name
* @param mixed $value
* @param int|bool $expiration
* @return bool
* @access protected
*/
protected
function
_addDBCache
(
$name
,
$value
,
$expiration
=
false
)
{
return
$this
->
_setDBCache
(
$name
,
$value
,
$expiration
,
'INSERT'
);
}
/**
* Sets rebuilding mode for given cache
*
* @param string $name
* @param int $mode
* @param int $max_rebuilding_time
* @param string $miss_type
* @return bool
* @access public
*/
public
function
rebuildDBCache
(
$name
,
$mode
=
null
,
$max_rebuilding_time
=
0
,
$miss_type
=
'M'
)
{
if
(
!
isset
(
$mode
)
||
$mode
==
kCache
::
REBUILD_NOW
)
{
$this
->
cacheHandler
->
storeStatistics
(
$name
,
$miss_type
);
if
(
!
$max_rebuilding_time
)
{
return
true
;
}
if
(
!
$this
->
_addDBCache
(
$name
.
'_rebuilding'
,
1
,
$max_rebuilding_time
)
)
{
$this
->
cacheHandler
->
storeStatistics
(
$name
,
'l'
);
return
false
;
}
$this
->
deleteDBCache
(
$name
.
'_rebuild'
);
$this
->
cacheHandler
->
storeStatistics
(
$name
,
'L'
);
}
elseif
(
$mode
==
kCache
::
REBUILD_LATER
)
{
$this
->
_setDBCache
(
$name
.
'_rebuild'
,
1
,
0
);
$this
->
deleteDBCache
(
$name
.
'_rebuilding'
);
}
return
true
;
}
/**
* Deletes key from database cache
*
* @param string $name
* @return void
* @access public
*/
public
function
deleteDBCache
(
$name
)
{
$sql
=
'DELETE FROM '
.
TABLE_PREFIX
.
'SystemCache
WHERE VarName = '
.
$this
->
Conn
->
qstr
(
$name
);
$this
->
Conn
->
Query
(
$sql
);
}
/**
* Increments serial based on prefix and it's ID (optional)
*
* @param string $prefix
* @param int $id ID (value of IDField) or ForeignKeyField:ID
* @param bool $increment
* @return string
* @access public
*/
public
function
incrementCacheSerial
(
$prefix
,
$id
=
null
,
$increment
=
true
)
{
$pascal_case_prefix
=
implode
(
''
,
array_map
(
'ucfirst'
,
explode
(
'-'
,
$prefix
)));
$serial_name
=
$pascal_case_prefix
.
(
isset
(
$id
)
?
'IDSerial:'
.
$id
:
'Serial'
);
if
(
$increment
)
{
if
(
defined
(
'DEBUG_MODE'
)
&&
DEBUG_MODE
&&
$this
->
Application
->
isDebugMode
())
{
$this
->
Application
->
Debugger
->
appendHTML
(
'Incrementing serial: <strong>'
.
$serial_name
.
'</strong>.'
);
}
$this
->
setCache
(
$serial_name
,
(
int
)
$this
->
getCache
(
$serial_name
)
+
1
);
if
(!
defined
(
'IS_INSTALL'
)
||
!
IS_INSTALL
)
{
// delete cached mod-rewrite urls related to given prefix and id
$delete_clause
=
isset
(
$id
)
?
$prefix
.
':'
.
$id
:
$prefix
;
$sql
=
'DELETE FROM '
.
TABLE_PREFIX
.
'CachedUrls
WHERE Prefixes LIKE '
.
$this
->
Conn
->
qstr
(
'%|'
.
$delete_clause
.
'|%'
);
$this
->
Conn
->
Query
(
$sql
);
}
}
return
$serial_name
;
}
/**
* Returns cached category informaton by given cache name. All given category
* information is recached, when at least one of 4 caches is missing.
*
* @param int $category_id
* @param string $name cache name = {filenames, category_designs, category_tree}
* @return string
* @access public
*/
public
function
getCategoryCache
(
$category_id
,
$name
)
{
$serial_name
=
'[%CIDSerial:'
.
$category_id
.
'%]'
;
$cache_key
=
$name
.
$serial_name
;
$ret
=
$this
->
getCache
(
$cache_key
);
if
(
$ret
===
false
)
{
if
(!
$category_id
)
{
// don't query database for "Home" category (ID = 0), because it doesn't exist in database
return
false
;
}
// this allows to save 2 sql queries for each category
$this
->
Conn
->
nextQueryCachable
=
true
;
$sql
=
'SELECT NamedParentPath, CachedTemplate, TreeLeft, TreeRight
FROM '
.
TABLE_PREFIX
.
'Categories
WHERE CategoryId = '
.
(
int
)
$category_id
;
$category_data
=
$this
->
Conn
->
GetRow
(
$sql
);
if
(
$category_data
!==
false
)
{
// only direct links to category pages work (symlinks, container pages and so on won't work)
$this
->
setCache
(
'filenames'
.
$serial_name
,
$category_data
[
'NamedParentPath'
]);
$this
->
setCache
(
'category_designs'
.
$serial_name
,
ltrim
(
$category_data
[
'CachedTemplate'
],
'/'
));
$this
->
setCache
(
'category_tree'
.
$serial_name
,
$category_data
[
'TreeLeft'
]
.
';'
.
$category_data
[
'TreeRight'
]);
}
}
return
$this
->
getCache
(
$cache_key
);
}
}
Event Timeline
Log In to Comment