FOSElasticaBundle: Setting analyzer for custom properties - symfony

I am using the FOSElasticaBundle in Symfony 3.3. I have registered an event listener on the POST_TRANSFORM event that computes and adds a custom property like this:
public function addCustomProperty(TransformEvent $event)
{
$document = $event->getDocument();
$custom = $this->anotherService->calculateCustom($event->getObject());
$document->set('custom', $custom);
}
Now I need to set the analyzer to be used for this property. How can I do that?
I already tried to add the custom field name to the type definition in my fos_elastica config but that causes an exception as the bundle then expects that property on my entity as well.

I finally found out that I could use dynamic_templates to set the desired analyzer like this:
fos_elastica:
indexes:
app:
types:
myentity:
dynamic_templates:
custom_field:
path_match: customfield.*
mapping:
analyzer: myanalyzer
properties:
...

Related

add a virtual property in easy-admin bundle

I'm currently working with the 2.3 version of the easy-admin bundle in Symfony 4.
I try to create a virtual property for the new view.
I have the following configuration
#config/packages/easy_admin.yaml
easy_admin:
entities:
Field:
class: App\Entity\Field
form:
fields:
- { type: tab, label: initial information, icon: pencil-alt }
- name
new:
fields:
- { property: toto, type: file }
and my entity file:
//src/Entity/Field.php
/**
* #ORM\Entity(repositoryClass="App\Repository\FieldRepository")
*/
class Field
{
public function setToto(?File $file): self
{
$this->setImage(new Image);
$this->getImage()->setImageFile($file);
}
as explain in the documentation the setter should be sufficient.
but when I reach the new page I get the following error:
Neither the property "toto" nor one of the methods "getToto()", "toto()", "isToto()", "hasToto()", "__get()" exist and have public access in class "App\Entity\Field".
which means that the page is looking for getter and not setter. Is it normal or did I make something wrong ?
I have just ran into this issue and I have solved it by adding the getter.
As you said, it is looking for getter but also setter.

Monolog handler ignoring yaml level

In Symfony 4.3 using Monolog, I have created a custom handler to push logs to AWS Firehose. Here is the constructor:
class FirehoseLogHandler extends AbstractProcessingHandler {
public function __construct(
FirehoseClient $firehoseClient,
FormatterInterface $formatter,
$streamName,
$level = Logger::INFO,
$bubble = true
) {
$this->firehoseClient = $firehoseClient;
$this->streamName = $streamName;
$this->formatter = $formatter;
parent::__construct($level, $bubble);
}
And here is my monolog.yaml config:
monolog:
handlers:
firehose_handler:
type: service
id: kinesis_stream_handler
main:
type: stream
handler: firehose_handler
level: error
channels: ["!event"]
services:
kinesis_stream_handler:
class: App\Logger\Handler\FirehoseLogHandler
arguments:
$firehoseClient: '#aws.firehose'
$formatter: '#App\Logger\Formatter\FirehoseLogFormatter'
$streamName: 'firehose-stream-test'
The problem that I am having is that the $level is always set to Logger::INFO (200), or whatever is set in the constructor. It seems to be ignoring what is set in the yaml config.
What am I doing wrong here? I know I could always add $level: 400 to the service declaration but that doesn't seem to make much sense. Appreciate any help in advance.
Handlers defined as type: service are used strictly as-is, since they are instances you have already constructed. They are not passed any arguments from the main monolog configuration; that would only apply to services it is constructing for you. So you do need to add $level as an explicit argument to your custom handler for this reason.
There may be some further confusion stemming from your main handler definition. While handler is a valid configuration key, it does not apply to a stream handler as it only makes sense for handlers that wrap others, such as filter. So that is simply being ignored.
The full list of handler types and what configuration keys actually apply to each can be found in the code here.

creating custom repository fos elastic search

im trying to make a simple custom repository in order to understand how elastic search repository works. the documentation is pretty straight forward but i still dont understand how it works, im getting this error ´The service definition "fos_elastica.manager" does not exist.´. so far i think my problem is in the controller since i dont understand how to intialize them, also i would like to know if im in the right way in my configuration of the custom repository and the simple query i made.
im getting this error with this configuration whenever i try to make a search,
The service definition "fos_elastica.manager" does not exist.
this is my configuration so far:
//app/config.yml
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
sava:
client: default
types:
blog:
mappings:
id:
type: integer
body : ~
title : ~
tags: ~
persistence:
identifier: id
driver: orm
model: sava\BlogBundle\Entity\TblPost
finder: ~
provider: ~
listener: ~
repository: sava\BlogBundle\SearchRepository\TblPostRepository
this is my controller action:
namespace sava\BlogBundle\Controller;
//custom querys
use FOS\ElasticaBundle\Manager\RepositoryManager;
use FOS\ElasticaBundle\Repository;
//
use Symfony\Component\DependencyInjection\ContainerBuilder;
class TblPostController extends Controller
{
public function getPostAction(Request $request)
{
$container = new ContainerBuilder();
$repositoryManager = $container->get('fos_elastica.manager');
$repository = $repositoryManager->getRepository('BlogBundle:TblPost');
$items2 = $repository->matchExact($categoria,$searchQuery );
return $this->render('savaBlogBundle:TblPost:index.html.twig', array(
'results' => $items2, 'entities' => $items2
));
}
this is my post repository:
<?php
namespace sava\BlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\ElasticaBundle\Repository;
class TblPostRepository extends FOS\ElasticaBundle\Repository
{
public function matchExact($campo, $searchQuery) {
//$finder = $this->get('fos_elastica.finder.sava.blog');
$query = new Query();
if($searchQuery=='')
{
$innerQuery = new Query\MatchAll();
}
else{
$innerQuery = new Query\Match();
$innerQuery->setField( $campo , array('query' => $searchQuery));
}
$query->setQuery($innerQuery);
$query->setSize(1000000);
$query->setExplain(true);
return $this->find($query);
}
}
and since im using yml this is my tblpost.orm, i did generate my entities.
whenever i do the get postaction it throws me that it cant find the container, and i dont see an example in how to properly intiaze it, also is this is how you make a custom query?
EDIT 1:
so i changed this:
$container = new ContainerBuilder();
$repositoryManager = $container->get('fos_elastica.manager');
to this:
$elastica = $this->container->get('fos_elastica.manager');// single entry point, no fancy services
$SearchRepository = $elastica->getRepository('savaBlogBundle:TblPostRepository');// single type
and im getting this error:
No search finder configured for sava\BlogBundle\Entity\TblPostRepository
I've just had the same issue, the soultion is that instead of savaBlogBundle:TblPostRepository you should use your entity, for example:
$SearchRepository = $elastica->getRepository('savaBlogBundle:TblPost`)
According your fatal error in title of the issue enter link description here
The main problem why did you get that mistake is that, you assigned the same TblPostRepository in (doctrine config for entity) and in fos_elastica.

How to fix "This repository can be attached only to ORM sortable listener" error in Gedmo sortable?

When usieing StofDoctrineExtensions (which is a Symfony2 port of Gedmo Doctrine Extensions) Sortable behaviour I kept on getting this error:
This repository can be attached only to ORM sortable listener
Since I could not easily find the answer in official docs I'm leaving an answer here for future reference.
You need to enable any listeners you are using. In this case, Sortable.
stof_doctrine_extensions:
default_locale: en_US
orm:
default:
sortable: true
For Symfony 4, add this configuration in /config/packages/stof_doctrine_extensions.yaml. For older versions of Symfony, add it to config.yml.
In order to use Sortable behaviour you need to add an event listener to your bundle's boot method
<?php
namespace Acme\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeDemoBundle extends Bundle
{
public function boot()
{
// get the doctrine 2 entity manager
$em = $this->container->get('doctrine.orm.default_entity_manager');
// get the event manager
$evm = $em->getEventManager();
$evm->addEventSubscriber(new \Gedmo\Sortable\SortableListener);
}
}

Symfony 2.1 Doctrine filters (enable/disable)

I'm currently implementing Doctrine filters in my Symfony2.1 project with the following setup:
<?php
namespace Acme\Bundle\Entity;
class Article {
/**
* #ORM\Column(type="string")
*/
private $status;
...
}
//app/config/config.yml
doctrine:
orm:
filters:
status:
class: Acme\Bundle\Filter\StatusFilter
enabled: false
....
//src/Acme/Bundle/Filter/StatusFilter.php
namespace Acme\Bundle\Filter;
use Acme\Bundle\Entity\Status;
class StatusFilter extends SQLFilter {
public function addFilterConstraint(ClassMetadata $target, $alias)
{
$filter =
$target->reflClass->implementsInterface('Acme\Bundle\Entity\Status')?
$alias . '.status = ' . Status::PUBLISHED : '';
return $filter;
}
}
Where Acme\Bundle\Entity\Status is just an interface.
The code is working as expected when the filter is enabled in config.yml.
The problem is that I cannot retrieve all articles for administration!
Is there a way to enable this filter for a certain bundle?
p.s. I know how to enable and disable the filter with the EntityManager,
I just cannot find the proper place to do it for the frontend Bundle.
my admin section is accessible by route prefix myadmin
www.example.com/myadmin/ -> admin section = disable filter (disabled by default in config)
www.example.com/... -> anything else = enable filter.
Looking at the Doctrine code, there are methods to enable and disable filters.
Once you have defined your filter in the config.yml file, you can enable/disable in a controller or service:
// 'status' is the unique name of the filter in the config file
$this->getDoctrine()->getManager()->getFilters()->enable('status');
$this->getDoctrine()->getManager()->getFilters()->disable('status');
Note: this was taken from Symfony 2.3. You would need to test this with previous versions of Symfony/Doctrine.
there is no notion of bundle at Doctrine level. The only way I see would be to detect which controller is used, by parsing its className (reflection, ...) during a kernel.request event, or a kernel.controller event.
Then, if you detect that your controller is in FrontendBundle, just disable/enable your doctrine filter.
If you prefer using routing to detect when to disable/enable, just use kernel.request event. You will have access to all request parameters, via $event->getRequest()->attributes->get('_controller') for example.

Resources