Appearance
Cheat Sheet
This is purely informative.
Change user password
shell
$ ./app/admin/console fos:user:change-password <username> <password>
...
$ ./app/admin/console fos:user:change-password admin ..admin
...
Config favicon.ico
Config the html-layout-header
setting to add the <link...
element.
Config header logo
It is a snippet configured in settings:
Admin -> Advanced admin -> Snippets -> snp-logo
Config the snp-logo
setting to add the <svg...
element.
Create the menu if it doesn't exist
We can create a menu using this url: site/menu/form. Example: https://admin-starbase.xalok.com/menu/form.
To create a menu for the covers, we will create one called admin-boards and then we can manage the menu.
Custom default/404 imagen
Cuando en un prouecto queremos reemplazar la imagen por defecto de Xalok por una custom podemos hacer lo siguiente:
- cambiar la imagen
~/codata/image_placeholder_source.jpg
- eliminar todas las imágenes
**/image_placeholder.jpg
del bucket. - solicitar a HS que purguen de cachés esas imágenes.
Scheduler Tasks
Stateful scheduled tasks
Sometimes when some configurations change, i.e. inside page templates, we need purge all site pages. The purge should be done slowly to not do much presure. The next scheluder count from zero to N in each execution heartbit, then ends using an exception. You can restart the process simply flipping the flip-flop
value:
php
// specific key to store this executor's state
$REDIS_STATE = "CustomStateExecutor";
// flip-flop resetting state, simply change flip-flop to reset values
$rstate = [
'flip-flop' => true,
'currentId' => 0
];
// services
$redis = $this->container->get('wf_cms.publish.manager');
// read current state
$redisStateKey = sprintf("%s:scheduler:%s", $redis->getPrefix(), $REDIS_STATE);
$cstate = json_decode($redis->getRedis()->get($redisStateKey), true) ?? $rstate;
if( $rstate['flip-flop'] != $cstate['flip-flop'] ) {
$cstate = $rstate;
}
// do something and update the state
$cstate['currentId'] = $cstate['currentId'] + 1;
// if you need a stopping condition use an exception
if( $cstate['currentId'] > 3 ) {
throw new \Exception("Process ended!");
}
// store the state
$redis->getRedis()->set($redisStateKey, json_encode($cstate));
// return info
$return = sprintf("Current Id := %d", $cstate['currentId']);
Purge all pages
php
/*
Purge all `page-{page-id}` from the MAX(page.id) down to 1.
You could see the current state using:
bastion:~$ redis-cli -h redis get $REDIS_STATE
Change `flip-flop` value to restart the process.
*/
// specific key to store this executor's state
$REDIS_STATE = "SlowPurgeAllPages";
// time ref
// | |
// V V
// [job][...waiting...][job][...waiting...]...
$timeRef = new \DateTime();
// flip-flop resetting state, simply change flip-flop to reset values
$rstate = [
'flip-flop' => false,
'lastTopId' => 0, // from MAX(page.id) to 0
'maxId' => 0, // MAX(page.id)
'chunkSize' => 100, // pages to purge every heartbit
'firstRun' => $timeRef // start time
->format(\DateTime::ATOM),
];
// services
$redis = $this->container->get('wf_cms.publish.manager');
$cacheManager = $this->container->get('FOS\\HttpCacheBundle\\CacheManager');
// read current state
$redisStateKey = sprintf("%s:scheduler:%s", $redis->getPrefix(), $REDIS_STATE);
$jstate = $redis->getRedis()->get($redisStateKey);
$restart = !$jstate;
$cstate = json_decode($jstate, true) ?? $rstate;
if( $restart || $rstate['flip-flop'] != $cstate['flip-flop'] ) {
$cstate = $rstate;
$pageRepository = $this->container->get('wf_cms.repository.page');
$cstate['maxId'] = $pageRepository
->createQueryBuilder('p')
->select('MAX(p.id) as maxId')
->getQuery()
->getSingleResult()['maxId'];
$cstate['lastTopId'] = $cstate['maxId'];
}
$firstRun = new \DateTime($cstate['firstRun']);
$chunkSize = intval($cstate['chunkSize']);
$lastTopId = intval($cstate['lastTopId']);
if($chunkSize < 1 || $chunkSize > 100000) {
throw new \Exception(sprintf("the specified chunk size of %d is wrong", $chunkSize));
}
if($lastTopId > intval($cstate['maxId'])) {
throw new \Exception("bad state, the lastTopId value is wrong, please restart");
}
if($lastTopId < 1) {
throw new \Exception("PROCESS END, no more pages to purge\n");
}
// do something and update the state
$chunkTo = $lastTopId;
$chunkFrom = $lastTopId - $chunkSize;
$purgeTags = [];
for ($i = $chunkFrom; $i <= $chunkTo; $i++) {
$purgeTags[] = "page-" . $i;
}
$cacheManager->invalidateTags($purgeTags);
// update and store the state
$cstate['lastTopId'] = $chunkFrom - 1;
$redis->getRedis()->set($redisStateKey, json_encode($cstate));
// return info
$elapsedSecs = $timeRef->getTimestamp() - $firstRun->getTimestamp();
$totalRuns = ceil($cstate['maxId'] / $chunkSize);
if($elapsedSecs < 1) {
$return = sprintf("Starting...\nTotal pages: %d\nTotal runs: %d\n",
$cstate['maxId'],
$totalRuns
);
} else {
$pendingRuns = ceil($cstate['lastTopId'] / $chunkSize);
$avgSecsPerRun = $elapsedSecs / ($totalRuns - $pendingRuns);
$pendingSecs = $pendingRuns * $avgSecsPerRun;
$return = sprintf("Running (%.1f %%)...\nRun %d of %d\nETA: %s\nLast Id: %d\n",
100.0 - 100.0 * $pendingRuns / $totalRuns,
$totalRuns - $pendingRuns, $totalRuns,
gmdate("H:i:s", ceil($pendingSecs)),
$chunkFrom
);
}