1. Go to this page and download the library: Download loyaltycorp/search library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
loyaltycorp / search example snippets
declare(strict_types=1);
namespace App\Services\Search;
use EonX\EasyEntityChange\DataTransferObjects\ChangedEntity;
use LoyaltyCorp\Search\Bridge\Doctrine\DoctrineSearchHandler;
use LoyaltyCorp\Search\DataTransferObjects\DocumentAction;
use LoyaltyCorp\Search\DataTransferObjects\DocumentDelete;
use LoyaltyCorp\Search\DataTransferObjects\DocumentUpdate;
use LoyaltyCorp\Search\DataTransferObjects\Handlers\ChangeSubscription;
use LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForChange;
use LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForDelete;
use LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForUpdate;
/**
* This handler represents a single index in Elasticsearch, and reacts to a single primary
* entity for building those indicies.
*
* The extends annotation below tells phpstan that we're creating a handler for dealing
* with Transactions only, and enables additional checks to ensure code correctness. For
* more details, check out PhpStan Generics.
*
* @extends DoctrineSearchHandler<Transaction>
*/
class TransactionHandler extends DoctrineSearchHandler
{
/**
* This method is used to define the Elasticsearch mappings. By convention, our indices should
* be defined with dynamic->strict wherever they can be, to avoid issues with mistakes in the
* transform method or the mappings being out of sync.
*
* {@inheritdoc}
*/
public static function getMappings(): array
{
return [
'doc' => [
'dynamic' => 'strict',
'properties' => [
'createdAt' => [
'type' => 'date',
],
// Additional mappings as 'value'],
fn (ChangedEntity $change) => $this->loadTransactionsFromMetadata($change)
);
// React to changes to the user's email address
yield new ChangeSubscription(
User::class,
['email'],
fn (ChangedEntity $change) => $this->loadTransactionsFromUser($change)
);
}
/**
* Loads related transactions from a metadata change.
*
* @phpstan-return iterable<ObjectForUpdate<Transaction>>
*
* @param \EonX\EasyEntityChange\DataTransferObjects\ChangedEntity $change
*
* @return \LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForChange[]
*/
public function loadTransactionsFromMetadata(ChangedEntity $change): iterable
{
if ($change->getClass() !== Metadata::class ||
\is_string($change->getIds()['metadataId'] ?? null) === false) {
return [];
}
$repository = $this->getEntityManager()->getRepository(Transaction::class);
return $repository->getSearchTransactionsForMetadataUpdate($change->getIds()['metadataId']);
}
/**
* Loads related transactions from a user.
*
* @phpstan-return iterable<ObjectForUpdate<Transaction>>
*
* @param \EonX\EasyEntityChange\DataTransferObjects\ChangedEntity $change
*
* @return \LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForChange[]
*/
public function loadTransactionsFromUser(ChangedEntity $change): iterable
{
if ($change->getClass() !== User::class ||
\is_string($change->getIds()['userId'] ?? null) === false) {
return [];
}
$repository = $this->getEntityManager()->getRepository(Transaction::class);
return $repository->getSearchTransactionsForUserUpdate($change->getIds()['userId']);
}
/**
* This method takes an ObjectForChange and returns a DocumentAction.
*
* Its primary purpose is to either decide that a document should be deleted or updated.
*
* {@inheritdoc}
*/
public function transform(ObjectForChange $change): ?DocumentAction
{
// We didnt get a $change that makes sense for this transform method.
if ($change->getClass() !== Transaction::class ||
($change->getObject() instanceof Transaction) === false) {
return null;
}
// If we got an ObjectForDelete and we have the searchId metadata,
// issue a delete action to search.
if ($change instanceof ObjectForDelete === true &&
\is_string($change->getMetadata()['searchId'] ?? null) === true) {
return new DocumentDelete($change->getMetadata()['searchId']);
}
// If we didnt get an Update or Delete we dont know what the system//
// wants, lets not do anything.
if ($change instanceof ObjectForUpdate === false) {
return null;
}
/**
* PHPStorm isnt capable of recognising that this is a Transaction even though
* we check it above. This is just for IDE compatibility.
*
* @var \App\Database\Entities\Transaction $transaction
*/
$transaction = $change->getObject();
// An object without an external id cannot be transformed.
if (\is_string($transaction->getExternalId()) === false) {
return null;
}
return new DocumentUpdate(
$transaction->getExternalId(),
[
'id' => $transaction->getId(),
'created_at' => $transaction->getCreatedAt(),
// ...
]
);
}
}
declare(strict_types=1);
namespace App\Database\Repositories;
use LoyaltyCorp\Search\Bridge\Doctrine\Interfaces\FillableRepositoryInterface;
use LoyaltyCorp\Search\Bridge\Doctrine\SearchRepositoryTrait;
use LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForUpdate;
/**
* @implements FillableRepositoryInterface<Transaction>
*/
class TransactionRepository extends Repository implements FillableRepositoryInterface
{
use SearchRepositoryTrait;
/**
* {@inheritdoc}
*
* @throws \Doctrine\ORM\ORMException
*/
public function getFillIterable(): iterable
{
return $this->doGetFillIterable(
$this->createQueryBuilder('e'),
$this->entityManager->getClassMetadata(Transaction::class),
Transaction::class
);
}
/**
* Returns an iterable of transactions that relate to a user.
*
* @phpstan-return array<ObjectForUpdate<Transaction>>
*
* @param string $metadataId
*
* @return \LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForUpdate[]
*
* @throws \Doctrine\ORM\ORMException
*/
public function getSearchTransactionsForMetadataUpdate(string $metadataId): iterable
{
$builder = $this->createQueryBuilder('t');
$builder->select('t.transactionId');
$builder->where(':metadata MEMBER OF t.metadata');
$builder->setParameter('metadata', $metadataId);
$index = 0;
foreach ($builder->getQuery()->iterate([], AbstractQuery::HYDRATE_SCALAR) as $result) {
yield new ObjectForUpdate(
Transaction::class,
['transactionId' => $result[$index++]['transactionId']]
);
}
}
/**
* Returns an iterable of transactions that relate to a user.
*
* @phpstan-return array<ObjectForUpdate<Transaction>>
*
* @param string $userId
*
* @return \LoyaltyCorp\Search\DataTransferObjects\Handlers\ObjectForUpdate[]
*
* @throws \Doctrine\ORM\ORMException
*/
public function getSearchTransactionsForUserUpdate(string $userId): iterable
{
$builder = $this->createQueryBuilder('t');
$builder->select('t.transactionId');
$builder->where('IDENTITY(t.user) = :user');
$builder->setParameter('user', $userId);
$index = 0;
foreach ($builder->getQuery()->iterate([], AbstractQuery::HYDRATE_SCALAR) as $result) {
yield new ObjectForUpdate(
Transaction::class,
['transactionId' => $result[$index++]['transactionId']]
);
}
}
/**
* {@inheritdoc}
*
* @throws \Doctrine\ORM\Mapping\MappingException
*/
public function prefillSearch(iterable $changes): void
{
$this->doPrefillSearch(
$this->createQueryBuilder('e'),
$this->entityManager->getClassMetadata(Transaction::class),
Transaction::class,
$changes
);
}
}
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.