Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
webhdx committed Apr 12, 2021
2 parents 4fa8309 + 5980d36 commit d573d70
Show file tree
Hide file tree
Showing 29 changed files with 1,323 additions and 113 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"nelmio/cors-bundle": "^2.0",
"pagerfanta/pagerfanta": "^2.1",
"ocramius/proxy-manager": "^2.2",
"doctrine/dbal": "^2.13.0",
"doctrine/orm": "^2.7",
"doctrine/doctrine-bundle": "^2.0",
"liip/imagine-bundle": "^2.3",
"oneup/flysystem-bundle": "^3.4",
Expand Down
139 changes: 26 additions & 113 deletions eZ/Bundle/EzPublishCoreBundle/Command/ReindexCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
use const DIRECTORY_SEPARATOR;
use Doctrine\DBAL\Connection;
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
use eZ\Publish\SPI\Persistence\Content\ContentInfo;
use eZ\Publish\Core\Search\Common\Indexer;
use eZ\Publish\Core\Search\Common\IncrementalIndexer;
use Doctrine\DBAL\Driver\Statement;
use eZ\Publish\SPI\Search\Content\IndexerGateway;
use Generator;
use eZ\Publish\SPI\Persistence\Content\Location\Handler;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
Expand All @@ -26,19 +26,12 @@
use Symfony\Component\Process\Process;
use RuntimeException;
use DateTime;
use PDO;

class ReindexCommand extends Command implements BackwardCompatibleCommand
{
/** @var \eZ\Publish\Core\Search\Common\Indexer|\eZ\Publish\Core\Search\Common\IncrementalIndexer */
private $searchIndexer;

/** @var \Doctrine\DBAL\Connection */
private $connection;

/** @var \eZ\Publish\SPI\Persistence\Content\Location\Handler */
private $locationHandler;

/** @var string */
private $phpPath;

Expand All @@ -57,29 +50,26 @@ class ReindexCommand extends Command implements BackwardCompatibleCommand
/** @var string */
private $projectDir;

/**
* @param \eZ\Publish\Core\Search\Common\IncrementalIndexer|\eZ\Publish\Core\Search\Common\Indexer $searchIndexer
* @param \Doctrine\DBAL\Connection $connection
* @param \eZ\Publish\SPI\Persistence\Content\Location\Handler $locationHandler
* @param \Psr\Log\LoggerInterface $logger
* @param string $siteaccess
* @param string $env
* @param bool $isDebug
* @param string|null $phpPath
*/
/** @var \eZ\Publish\SPI\Search\Content\IndexerGateway */
private $gateway;

/** @var \eZ\Publish\SPI\Persistence\Content\Location\Handler */
private $locationHandler;

public function __construct(
$searchIndexer,
Connection $connection,
Handler $locationHandler,
IndexerGateway $gateway,
LoggerInterface $logger,
string $siteaccess,
string $env,
bool $isDebug,
string $projectDir,
string $phpPath = null
) {
$this->gateway = $gateway;
$this->searchIndexer = $searchIndexer;
$this->connection = $connection;
$this->locationHandler = $locationHandler;
$this->phpPath = $phpPath;
$this->logger = $logger;
Expand Down Expand Up @@ -259,16 +249,18 @@ protected function indexIncrementally(
}

if ($since = $input->getOption('since')) {
$stmt = $this->getStatementContentSince(new DateTime($since));
$count = (int)$this->getStatementContentSince(new DateTime($since), true)->fetchColumn();
$count = $this->gateway->countContentSince(new DateTime($since));
$generator = $this->gateway->getContentSince(new DateTime($since), $iterationCount);
$purge = false;
} elseif ($locationId = (int) $input->getOption('subtree')) {
$stmt = $this->getStatementSubtree($locationId);
$count = (int) $this->getStatementSubtree($locationId, true)->fetchColumn();
/** @var \eZ\Publish\SPI\Persistence\Content\Location\Handler */
$location = $this->locationHandler->load($locationId);
$count = $this->gateway->countContentInSubtree($location->pathString);
$generator = $this->gateway->getContentInSubtree($location->pathString, $iterationCount);
$purge = false;
} else {
$stmt = $this->getStatementContentAll();
$count = (int) $this->getStatementContentAll(true)->fetchColumn();
$count = $this->gateway->countAllContent();
$generator = $this->gateway->getAllContent($iterationCount);
$purge = !$input->getOption('no-purge');
}

Expand Down Expand Up @@ -302,10 +294,15 @@ protected function indexIncrementally(
$progress->start($iterations);

if ($processCount > 1) {
$this->runParallelProcess($progress, $stmt, (int) $processCount, (int) $iterationCount, $commit);
$this->runParallelProcess(
$progress,
$generator,
(int)$processCount,
$commit
);
} else {
// if we only have one process, or less iterations to warrant running several, we index it all inline
foreach ($this->fetchIteration($stmt, $iterationCount) as $contentIds) {
foreach ($generator as $contentIds) {
$this->searchIndexer->updateSearchIndex($contentIds, $commit);
$progress->advance(1);
}
Expand All @@ -326,14 +323,12 @@ protected function indexIncrementally(
*/
private function runParallelProcess(
ProgressBar $progress,
Statement $stmt,
Generator $generator,
int $processCount,
int $iterationCount,
bool $commit
): void {
/** @var \Symfony\Component\Process\Process[]|null[] */
$processes = array_fill(0, $processCount, null);
$generator = $this->fetchIteration($stmt, $iterationCount);
do {
/** @var \Symfony\Component\Process\Process $process */
foreach ($processes as $key => $process) {
Expand Down Expand Up @@ -372,88 +367,6 @@ private function runParallelProcess(
} while (!empty($processes));
}

/**
* @param DateTime $since
* @param bool $count
*
* @return \Doctrine\DBAL\Driver\Statement
*/
private function getStatementContentSince(DateTime $since, $count = false)
{
$q = $this->connection->createQueryBuilder()
->select($count ? 'count(c.id)' : 'c.id')
->from('ezcontentobject', 'c')
->where('c.status = :status')->andWhere('c.modified >= :since')
->orderBy('c.modified')
->setParameter('status', ContentInfo::STATUS_PUBLISHED, PDO::PARAM_INT)
->setParameter('since', $since->getTimestamp(), PDO::PARAM_INT);

return $q->execute();
}

/**
* @param mixed $locationId
* @param bool $count
*
* @return \Doctrine\DBAL\Driver\Statement
*
* @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
*/
private function getStatementSubtree($locationId, $count = false)
{
$location = $this->locationHandler->load($locationId);
$q = $this->connection->createQueryBuilder()
->select($count ? 'count(DISTINCT c.id)' : 'DISTINCT c.id')
->from('ezcontentobject', 'c')
->innerJoin('c', 'ezcontentobject_tree', 't', 't.contentobject_id = c.id')
->where('c.status = :status')
->andWhere('t.path_string LIKE :path')
->setParameter('status', ContentInfo::STATUS_PUBLISHED, PDO::PARAM_INT)
->setParameter('path', $location->pathString . '%', PDO::PARAM_STR);

return $q->execute();
}

/**
* @param bool $count
*
* @return \Doctrine\DBAL\Driver\Statement
*/
private function getStatementContentAll($count = false)
{
$q = $this->connection->createQueryBuilder()
->select($count ? 'count(c.id)' : 'c.id')
->from('ezcontentobject', 'c')
->where('c.status = :status')
->setParameter('status', ContentInfo::STATUS_PUBLISHED, PDO::PARAM_INT);

return $q->execute();
}

/**
* @param \Doctrine\DBAL\Driver\Statement $stmt
* @param int $iterationCount
*
* @return \Generator Return an array of arrays, each array contains content id's of $iterationCount.
*/
private function fetchIteration(Statement $stmt, $iterationCount)
{
do {
$contentIds = [];
for ($i = 0; $i < $iterationCount; ++$i) {
if ($contentId = $stmt->fetch(PDO::FETCH_COLUMN)) {
$contentIds[] = $contentId;
} elseif (empty($contentIds)) {
return;
} else {
break;
}
}

yield $contentIds;
} while (!empty($contentId));
}

/**
* @param array $contentIds
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

final class EntityManagerFactoryServiceLocatorPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
$entityManagerFactory = $container->getDefinition('ibexa.doctrine.orm.entity_manager_factory');

$ibexaEntityManagers = $this->getIbexaEntityManagers($container);
$entityManagerFactory->setArgument(
'$serviceLocator',
ServiceLocatorTagPass::register($container, $ibexaEntityManagers)
);
}

private function getIbexaEntityManagers(ContainerBuilder $container): array
{
$entityManagers = [];
foreach ($container->getParameter('doctrine.entity_managers') as $name => $serviceId) {
if (false === strpos($name, 'ibexa_')) {
continue;
}

$entityManagers[$serviceId] = new Reference($serviceId);
}

return $entityManagers;
}
}
Loading

0 comments on commit d573d70

Please sign in to comment.