Symfony doesn't remove cache by tags - symfony

Symfony version: 3.4.9
Reproducing:
$cache = new TagAwareAdapter($this->get('cache.app'));
$pagination = $cache->getItem(PostTypeDictionary::CACHE_MEDIA_PREFIX . $postType . $request->get('page', 1));
if (!$pagination->isHit()) {
$data = getSomeData();
$pagination->tag(
[
PostTypeDictionary::CACHE_MEDIA_PREFIX,
PostTypeDictionary::CACHE_MEDIA_PREFIX . $postType,
]
);
$pagination->set($data);
$cache->save($pagination);
} else {
$data = $pagination->get();
}
In redis i see two keys:
1) "zG3lSHyaSM:\x00tags\x00cache.media.01"
2) "zG3lSHyaSM:cache.media.01"
First contains: "a:2:{s:12:\"cache.media.\";i:0;s:13:\"cache.media.0\";i:0;}"
Second contains data
Then i call cache clearing by tags:
(new TagAwareAdapter($this->get('cache.app')))->invalidateTags([PostTypeDictionary::CACHE_MEDIA_PREFIX]);
Redis store one more key "zG3lSHyaSM:cache.media.\x00tags\x00", which contains: "i:1;"
And that's all, old cache available.
Another cache adapters have the same problem.
What i'm doing wrong?

I found that Symfony's cache component has a bug in a most recent version (3.4.9). I think it's related to https://github.com/symfony/cache/commit/51a9eef3091b2c06f63d8b1b98de9d101b5e0e77 . Simply downgrading to 3.4.8 solved this issue for me.

Related

Symfony validator translations

I just started using symfony validator and i really like it except translation part, currently it uses my own translator lib, but i found validator.LOCALE.xlf files where are translations for almost all languages stored, and i can't figure out how to use them.
My current validator registering code is
$container->register('validator', \Symfony\Component\Validator\Validator\ValidatorInterface::class)
->setFactory(
[
new Reference('validator.builder'),
'getValidator'
]
);
$container->register('validator.builder', \Symfony\Component\Validator\ValidatorBuilderInterface::class)
->setFactory(
[
\Symfony\Component\Validator\Validation::class,
'createValidatorBuilder'
]
)
->addMethodCall(
'setTranslator',
[
new Reference('translator') // Symfony translatorInterface
]
)
->addMethodCall(
'setTranslationDomain',
[
'messages'
]
);
It looks like i checked already whole validator structure, like RecursiveValidator, ContextualValidator, Contexts and etc, but just somewhere missing one single param, on another hand ConstraintViolationBuilder just simply takes passed translator and trying to translate constraint message through it, no attempts to use any xlf files.
Just force search through all validator library files gave no result too.
Symfony guilde didn't helped too, because it offers to use default error sentences as a translation key, and use this "keys" in your own translations files, but why copy already translated sentences to your own file, and also create a mess with keys pattern (for example i use snake case) when there is already structured files exists (i am talking about .xlf)?
Solution is to add xlf file loader to your translator, and pass it .xlf translations as a resource.
Something like that
$container->register('translator.xlf_file_loader', \Symfony\Component\Translation\Loader\XliffFileLoader::class);
$container->register('translator.php_file_loader', \Symfony\Component\Translation\Loader\PhpFileLoader::class);
$container->register('translator', \Project\Framework\Translation\Translator::class)
->addArgument(
new Reference('service_container')
)
->addMethodCall(
'addLoader',
[
'php',
new Reference('translator.php_file_loader')
]
)
->addMethodCall(
'addLoader',
[
'xlf',
new Reference('translator.xlf_file_loader')
]
)
->addMethodCall('addResource', ['php', __DIR__ . '/../translation/lt.php', 'lt'])
->addMethodCall('addResource', ['php', __DIR__ . '/../translation/en.php', 'en'])
->addMethodCall('addResource', ['php', __DIR__ . '/../translation/ru.php', 'ru'])
->addMethodCall('addResource', ['xlf', __DIR__ . '/../../vendor/symfony/validator/Resources/translations/validators.lt.xlf', 'lt'])
->addMethodCall(
'setFallbackLocales',
[
['lt']
]
);
Have you simply tried to either
change the locale in the app configuration:
# config/packages/translation.yaml
framework:
default_locale: 'en'
translator:
fallbacks: ['en']
Documentation
change the locale based on (user) input:
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
// some logic to determine the $locale
$request->setLocale($locale);
}
Documentation

How clear routing cache in Symfony 2

I override routing loader (routing.loader) for set requirements key {_locale} in all my paths and set defaults this key. All locales saved in database. And i want clear routing cache (Matcher and Dumper cache class) after save new locale in database, because requirements parameter load from DB.
Thank.
Symfony cached route files:
appDevUrlMatcher.php
appDevUrlGenerator.php
in your cache dir, var/cache/dev(prod)
just delete these files
protected function warmUpRouteCache() {
$router = $this->get('router');
$filesystem = $this->get('filesystem');
$kernel = $this->get('kernel');
$cacheDir = $kernel->getCacheDir();
foreach (array('matcher_cache_class', 'generator_cache_class') as $option) {
$className = $router->getOption($option);
$cacheFile = $cacheDir . DIRECTORY_SEPARATOR . $className . '.php';
$filesystem->remove($cacheFile);
}
$router->warmUp($cacheDir);
}
it works for me.
php app/console cache:clear
php app/console cache:clear --help
Additional cache warm up tasks are executed after clearing the cache in order to have regenerated caches available during runtime - see detailed help for further information.
https://symfony.com/doc/3.4/console/usage.html
https://symfony.com/doc/4.0/console/usage.html

Must manually load PHP ActiveRecord models

I'm drawing a blank. I have code working locally (which is MAMP). When moving to a nginx ubuntu box (running php-fpm), for some reason, phpactiverecord is acting up.
I finally traced it down to this - All of my model classes, I have to load manually. If I add a require_once() underneath my code, then it works fine. If I don't, then I get errors like:
PHP Fatal Error: Class not found ... on the models I've created..
Does anyone have ANY idea what direction I could troubleshoot this in? I checked permissions to the models folder (which is not in the public root), echo'd out the path that is sent over to cfg->set_model_directory is correct, etc..
This sound like a nginx or php thing? I'm guessing nginx since this works on my MAMP?
Doesn't work:
ActiveRecord\Config::initialize(
function ($cfg) {
$cfg->set_model_directory(BASE_PATH . '/models');
$cfg->set_connections(
array(
'development' => 'mysql://blah:removed#localhost/com_dbname'
)
);
}
);
Works:
ActiveRecord\Config::initialize(
function ($cfg) {
$cfg->set_model_directory(BASE_PATH . '/models');
$cfg->set_connections(
array(
'development' => 'mysql://blah:removed#localhost/com_dbname'
)
);
}
);
require_once(BASE_PATH . '/models/model1.php');
require_once(BASE_PATH . '/models/model2.php');
Update
Adding in actual code to help identify issue:
require_once ('../lib/php-activerecord/ActiveRecord.php');
ActiveRecord\Config::initialize(
function ($cfg) {
$cfg->set_model_directory('/var/www/uc1/models');
$cfg->set_connections(
array(
'development' => 'mysql://test_usr:test_pwd#localhost/test_db'
)
);
}
);
require_once ('/var/www/uc1/models/ucurls.php'); //Name of model file. Must manually include to get this to work on my nginx server.
$_record = UCUrls::find_by_urlkey('example.com/123');
echo "urlkey=" . $_record->urlkey;
I solved this issue in windows adding a line in the file ActiveRecord.php,
in the function activerecord_autoload($class_name)
at the line 39 or 40
$file = "$root/$class_name.php";
//add this line
$file = strtolower($file);
Set trace in ActiveRecord.php too look where are ActiveRecord is searching for models.
But I think your issue is in filesystem - Mac OS X by default uses Case Insensitive filesystem, while Ubuntu's Case Sensitive filesystem.
So your model UCUrls should be in file /var/www/uc1/models/UCUrls.php, not in /var/www/uc1/models/ucurls.php

How to load and cache translations?

I'm using gettext translations for SF2 and I arrange my translation files in different folder structure than the normal bundle (I kind of created my own mini plugin system for some specific needs).
In any case, this is how I'm loading my translation files:
$finder = new Finder();
$finder->files()->filter(function (\SplFileInfo $file)
{
return 2 === substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename());
})->in($dirs);
foreach ($finder as $file) {
// filename is domain.locale.format
list($domain, $locale, $format) = explode('.', $file->getBasename(), 3);
// we have to add resource right away or it will be too late
$translator->addResource($format, (string)$file, $locale, $domain);
}
It works well, the only problem is that it is not cached which is not very efficient. I wonder what I should do instead to cache these translation?
My problem was that I forgot the declare translator in the config file and thus the translation pass doesn't work
framework:
translator: { fallback: %locale% }

PHPExcel Bundle in Symfony2: Declaration of PHPExcel_Style_Color error

I install this bundle:
https://github.com/liuggio/ExcelBundle
In my Symfony2, basically add:
[PHPExcel]
git=http://github.com/PHPOffice/PHPExcel.git
target=/phpexcel
version=origin/master
[n3bStreamresponse]
git=git://github.com/liuggio/Symfony2-StreamResponse.git
target=n3b/src/n3b/Bundle/Util/HttpFoundation/StreamResponse
[LiuggioExcelBundle]
git=https://github.com/liuggio/ExcelBundle.git
target=/bundles/Liuggio/ExcelBundle
to deps, update Autoload.php and AppKernel.php and use this Action in one controller:
$excelService = $this->get('xls.service_xls2007');
$excelService->excelObj->getProperties()
->setTitle("Reunión comercial")
->setDescription("Reunión Comercial - Generación automática desde la aplicación de RRHH.");
$excelService->excelObj->getActiveSheet()->setTitle('Reunión Comercial');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$excelService->excelObj->setActiveSheetIndex(0);
//create the response
$response = $excelService->getResponse();
$response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment;filename=reuComercial-'.date("Y_m_d_His").'.xls');
// If you are using a https connection, you have to set those two headers for compatibility with IE <9
/*$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=1');
*/
$excelService->setActiveSheetIndex(0)
->setCellValue('A1', 'Lead')
->setCellValue('B1', 'Peticion')
->setCellValue('C1', 'Estado Candidato')
->setCellValue('D1', 'Nombre Candidato')
->setCellValue('E1', 'Apellido Candidato')
->setCellValue('F1', 'Cliente')
->setCellValue('G1', 'Descripcion');
$em = $this->getDoctrine()->getEntityManager();
$data = $em->getRepository('OportunidadBundle:Oportunidad')->reunionComercial();
$aux = 2;
foreach ($data as $row)
{
$excelService->setActiveSheetIndex(0)
->setCellValue('A'.$aux, $row->Lead)
->setCellValue('B'.$aux, $row->Peticion)
->setCellValue('C'.$aux, $row->Estado_Candidato)
->setCellValue('D'.$aux, $row->Nombre_Candidato)
->setCellValue('E'.$aux, $row->Apellido_Candidato)
->setCellValue('F'.$aux, $row->Cliente)
->setCellValue('G'.$aux, $row->Descripcion);
$aux++;
};
$excelService->getStreamWriter()->write( $filename );
return $response;
And I get this error :(
Runtime Notice: Declaration of PHPExcel_Style_Color::bindParent() should be compatible with that of PHPExcel_Style_Supervisor::bindParent() in C:\Program Files\EasyPHP-5.3.8.1\www\www\www\intranet\vendor\phpexcel\Classes\PHPExcel\Style\Color.php line 36
I have no idea what this means, because there are many things in PHP that still escape me :/
It's a problem with pulling the latest development branch code rather than tagged releases: develop branch code is never guaranteed to be in a state where you can simply run it.
I've modified the signatures for the bindParent() method so that this particular notice won't occur again

Resources