Class not found when trying to index documents using Solr with Symfony2 - symfony

I am very new to Solr and I am probably missing something simple however, having followed Xavier Briand's presentation I have set up Symfony2, Solarium and Nelmio\SolariumBundle.
"nelmio/solarium-bundle": "2.0.*#dev",
"solarium/solarium": "3.0.*"
Having implemented a toSolrDocument method for my doctrine php object.
public function toSolrDocument(\Solarium_Document_ReadWrite $doc)
{
$doc->id = $this->getId();
$doc->description = $this->getTitle();
$doc->path = "path";
return $doc;
}
I am faced with the following error.
Catchable Fatal Error: Argument 1 passed to ::toSolrDocument() must be an instance of Solarium_Document_ReadWrite, instance of Solarium\QueryType\Update\Query\Document given, called in Controller.php
The controller calling this toSolrDocument method has the following function
public function indexItems(){
$client = $this->get('solarium.client');
// get an update query instance
$update = $client->createUpdate();
// create documents
$documents = array();
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('<Bundle>:<Object>');
$items = $repo->findAll();
foreach ($items as $item) {
$documents[] = $item->toSolrDocument($update->createDocument());
}
// add the documents and a commit command to the update query
$update->addDocuments($documents);
$update->addCommit();
// this executes the query and returns the result
$result = $client->update($update);
}
Most of this method again comes directly from Xavier's presentation and it is clear to see that the method $update->createDocument() does not return the correct type. In fact it returns an instance of the my php object. Does anyone know where I am going wrong here? Another thing that might be of help is that even when I try to pass a Solarium Document directly I get an exception.
foreach ($items as $item) {
$rw_item = new \Solarium_Document_ReadWrite();
$documents[] = $item->toSolrDocument($rw_item);
}
The exception is
FatalErrorException: Error: Class 'Solarium_Document_ReadWrite' not found in
I can't seem to find this class in any of the bundles and I am wondering if my setup might be causing the issues. Any help would be very much appreciated.
One additional point to note is that when I am running the solr jar I see the query requests come in from my symfony2 page it is only this indexing action that I can not work out so the config may be alright and I am miss understanding the use of the bundle.

You just need to use the correct class for the argument.
use Solarium\QueryType\Select\Result\AbstractDocument;
...
public function toSolrDocument(AbstractDocument $doc)
{
You could also not type hint it:
public function toSolrDocument($doc)
{

Related

Symfony connect with algolia problem get Argument #1 ($object) must be of type object, int given

I have a question: I need to get communication with algolia, but i cannot get that work, since of leak of documentation. I have symfony 5.4 but algora docs provide only for version 4, second when I trying to get some of my entities indexed i get stuck at the point when i have to provide entityManager which suppose to implement ObjectManager, but that one it is not wired in the service. And how many people suggest we should not use this directly and use EntityManagerInteface instead. So how i have to index my Entity?
What i did:
composer require algolia/search-bundle
Added credentials:
ALGOLIA_APP_ID="U1RFIHY01W"
ALGOLIA_API_KEY="YourAPIKey"
Trying to index in the controller for testing:
public function searchPosts(Post $post, ManagerRegistry $em): JsonResponse
{
$posts = $this->postRepository->searchPosts('82819');
$postsArray = [];
/**#var Post $post */
foreach ($posts as $post){
$postsArray = $post->normalize();
}
$this->searchService->index($em->getManager(), $postsArray);
return new JsonResponse($this->searchService->getConfiguration());
}
Right now since i use ManagerRegestry i get an error:
get_class(): Argument #1 ($object) must be of type object, int given
Can you help me work around? Thank you
Separate the two instructions with :
$entityManager= $em->getManager();
and then
$this->searchService->index($entityManager, $lpostsArray);

why i got error inspite of that correctly set value to entity?

Hello my website is made by symfony and mysql.
Now im stuck in this error.
publisher_id cannot be null.
this errror means that publisher_id column of volume table can not be null.
this error is correct but i set value to publisher_id
and i did var_dump like below and i got correct Entity.
$volume = new Volume(); //instanciate Volume Entity.
$volume->setISBN($ISBN);
$volume->setStorePublisher($publisher); //set Publisher Entity to Volume Entity.
var_dump($publisher->getId()); //correct id shown.why no publisher id???
$volume->setCreatedAt(Context::now());
$volume->setUpdatedAt(Context::now());
$em = Context::getEntityManagerWrite();
$em->transactional(function (EntityManager $em) use (&$volume) {
$volume = $em->merge($volume); // i got error here.why ??
$em->flush();
//....
}
Your Error:
To begin with your problem you're trying to merge an unmanaged Entity,
Persist it inside the em first as such :
$volume = new Volume();
$volume->setISBN($ISBN);
$volume->setStorePublisher($publisher);
$volume->setCreatedAt(Context::now());
$volume->setUpdatedAt(Context::now());
$em->persist($volume);
// do stuff
FYI:
in you entity add the __construct method to remove this ugly createAt()from your controller
class Volume {
public function __construct()
{
$this->setCreateAt(new \DateTime());
}
}
For the updateAt() you can use services as shown in the Doc. The objective is to keep your Controlleras light as possible.

Handling Form errors in the controller ( Ajax call )

I'd like to have the field name in addition to the error message.
I performed the following set of instructions to put all errors into an array :
$errors= array();
foreach ($newRdvForm->getErrors(true) as $key => $error) {
$errors[$key] = $error->getMessage();
}
So what can i to have the field name of each input ?
If there are other method, feel free to publish it
The FormInterface::getErrors() method returns a FormErrorIterator instance. The underlying FormError objects provide a getOrigin() method which returns the FormInterface the error relates to.

Duplicating extbase repository object

In my extbase/fluid project,in addition to standard actions such as create,delete,list etc, I want to create a duplicate of a model class object which are stored in a repository. Using findall(), all objects are displayed in a list and corresponding actions such as delete,edit are displayed next to each. For duplicating an object, I have created a duplicate action in the corresponding controller and here is the code:
public function dupcliateAction(Tx_CcCompanylogin_Domain_Model_MyObject $testObject)
{
$this->myObjectRepository->add($testObject);
$this->redirect('list');//Lists the objects again from the repository
}
Seems straitforward enough but no new object is added to the repository and I am not getting an error.I have checked the documentation and there is no explicit method available for duplicating.
For those who may concern:
You don't need to call the reflection-api at this point.
You only need to implement a method called e.g. resetUid() in your model like this:
public function resetUid() {
$this->uid = NULL;
$this->_setClone(FALSE);
}
then you can use the magic clone method to clone the object in your controller. after that you have to call the new resetUid() method and then you are able to persist the new object with the old properties.
Note : When an object is cloned, PHP 5 will perform a shallow copy of all of the object's properties. Any properties that are references to other variables, will remain references.
Alternative you can use reflection to create a (deep) copy of your object.
$productClone = $this->objectManager->create('Tx_Theext_Domain_Model_Product');
// $product = source object
$productProperties = Tx_Extbase_Reflection_ObjectAccess::getAccessibleProperties($product);
foreach ($productProperties as $propertyName => $propertyValue) {
Tx_Extbase_Reflection_ObjectAccess::setProperty($productClone, $propertyName, $propertyValue);
}
// $productAdditions = ObjectStorage property
$productAdditions = $product->getProductAddition();
$newStorage = $this->objectManager->get('Tx_Extbase_Persistence_ObjectStorage');
foreach ($productAdditions as $productAddition) {
$productAdditionClone = $this->objectManager->create('Tx_Theext_Domain_Model_ProductAddition');
$productAdditionProperties = Tx_Extbase_Reflection_ObjectAccess::getAccessibleProperties($productAddition);
foreach ($productAdditionProperties as $propertyName => $propertyValue) {
Tx_Extbase_Reflection_ObjectAccess::setProperty($productAdditionClone, $propertyName, $propertyValue);
}
$newStorage->attach($productAdditionClone);
}
$productClone->setProductAddition($newStorage);
// This have to be repeat for every ObjectStorage property, or write a service.
For me, the Solution "Clone $Object and resetUid() in the Modell" does not work .. maybe this solution had worked in older TYPO3 Versions but in 7.6. LTS it throws an exception
#1222871239: The uid "61" has been modified, that is simply too much.
so maybe someone can find my solution helpful as it is much less code than the other reflection Solution: (and you do not have to think about to set all single properties .. )
Given: an Object called $registrant with all Data.
Wanted Result: a copy of that Object with same Data, but new Uid ..
/** #var \JVE\JvEvents\Domain\Model\Registrant $newregistrant */
$newregistrant = $this->objectManager->get( "JVE\\JvEvents\\Domain\\Model\\Registrant") ;
$properties = $registrant->_getProperties() ;
unset($properties['uid']) ;
foreach ($properties as $key => $value ) {
$newregistrant->_setProperty( $key , $value ) ;
}
I think the add command ignores objects that already exist.
You could try to clone the object and then add the clone to the repository $copy_of_object = clone $object;. Or maybe create a new Object with all the same properties.

Symfony2 repository query not working

I am developing an application using Symfony2 and DQL for building some queries in the repositories. I have the next code in the controller:
$emGalPak = $this->getDoctrine()->getEntityManager();
$OsatugabeKop = $emGalPak->getRepository('AnotatzaileaAnotatzaileaBundle:GalderaPaketea')
->getOsatugabeKop();
and this is the query I built in the repository corresponding to the entity mentioned above:
<?php
namespace Anotatzailea\AnotatzaileaBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* GalderaPaketeaRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class GalderaPaketeaRepository extends EntityRepository
{
public function getOsatugabeKop()
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where('c.Osatua = 0')
$Emaitza = $qb->getQuery()->getResult();
return sizeof($Emaitza);
}
}
When running the code it shows the next error:
Parse error: syntax error, unexpected T_VARIABLE in /var/www/Symfony/src/Anotatzailea/AnotatzaileaBundle/Repository/GalderaPaketeaRepository.php on line 20
Any idea on how I can solve this error?
This has nothing to do with your query not working.
When you see a "Parse error" that means your PHP code itself is improperly formatted and the PHP engine cannot even parse it, let alone run it.
In this particular case, you're missing a semicolon at the end of your expression creating the query builder.
public function getOsatugabeKop()
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where('c.Osatua = 0'); // <--- right there
$Emaitza = $qb->getQuery()->getResult();
return sizeof($Emaitza);
}
When you get the unexpected T_VARIABLE error that's almost always because you omitted a semicolon and the parser encountered a variable before it thought it should. It's easier to see the mistake if you take out the whitespace.
// Bad Code, two lines
$now = time()
$one = 1;
// Bad Code, one line
$now = time()$one = 1;
// ----------^ Pretty obvious now that a semicolon is missing
// And that a variable was encountered unexpectedly
Cheers
Semicolon missing after where line.

Resources