Added dependency on shlinkio/shlink-importer

This commit is contained in:
Alejandro Celaya 2020-10-22 18:12:22 +02:00
parent 0686ac2fb1
commit 33d3837795
7 changed files with 97 additions and 0 deletions

View File

@ -45,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
* [#837](https://github.com/shlinkio/shlink/issues/837) Drastically improved performance when creating a new shortUrl and providing `findIfExists = true`.
## 2.3.0 - 2020-08-09
#### Added

View File

@ -53,6 +53,7 @@
"shlinkio/shlink-common": "^3.2.0",
"shlinkio/shlink-config": "^1.0",
"shlinkio/shlink-event-dispatcher": "^1.4",
"shlinkio/shlink-importer": "^1.0",
"shlinkio/shlink-installer": "^5.1.0",
"shlinkio/shlink-ip-geolocation": "^1.5",
"symfony/console": "^5.1",

View File

@ -2,7 +2,9 @@
declare(strict_types=1);
use GuzzleHttp\Client;
use Mezzio\Container;
use Psr\Http\Client\ClientInterface;
return [
@ -13,6 +15,10 @@ return [
],
],
'aliases' => [
ClientInterface::class => Client::class,
],
'lazy_services' => [
'proxies_target_dir' => 'data/proxies',
'proxies_namespace' => 'ShlinkProxy',

View File

@ -21,6 +21,7 @@ return (new ConfigAggregator\ConfigAggregator([
Diactoros\ConfigProvider::class,
Common\ConfigProvider::class,
Config\ConfigProvider::class,
Importer\ConfigProvider::class,
IpGeolocation\ConfigProvider::class,
EventDispatcher\ConfigProvider::class,
Core\ConfigProvider::class,

View File

@ -10,6 +10,7 @@ use Psr\EventDispatcher\EventDispatcherInterface;
use Shlinkio\Shlink\Core\Domain\Resolver;
use Shlinkio\Shlink\Core\ErrorHandler;
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
use Shlinkio\Shlink\Importer\ImportedLinksProcessorInterface;
return [
@ -42,6 +43,12 @@ return [
Resolver\PersistenceDomainResolver::class => ConfigAbstractFactory::class,
Mercure\MercureUpdatesGenerator::class => ConfigAbstractFactory::class,
Importer\ImportedLinksProcessor::class => ConfigAbstractFactory::class,
],
'aliases' => [
ImportedLinksProcessorInterface::class => Importer\ImportedLinksProcessor::class,
],
],
@ -96,6 +103,8 @@ return [
Resolver\PersistenceDomainResolver::class => ['em'],
Mercure\MercureUpdatesGenerator::class => ['config.url_shortener.domain'],
Importer\ImportedLinksProcessor::class => ['em', Resolver\PersistenceDomainResolver::class],
],
];

View File

@ -14,6 +14,8 @@ use Shlinkio\Shlink\Core\Domain\Resolver\SimpleDomainResolver;
use Shlinkio\Shlink\Core\Exception\ShortCodeCannotBeRegeneratedException;
use Shlinkio\Shlink\Core\Model\ShortUrlEdit;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
use Shlinkio\Shlink\Importer\Model\ShlinkUrl;
use function count;
use function Shlinkio\Shlink\Core\generateRandomShortCode;
@ -33,6 +35,7 @@ class ShortUrl extends AbstractEntity
private ?Domain $domain = null;
private bool $customSlugWasProvided;
private int $shortCodeLength;
private ?string $source = null;
public function __construct(
string $longUrl,
@ -54,6 +57,27 @@ class ShortUrl extends AbstractEntity
$this->domain = ($domainResolver ?? new SimpleDomainResolver())->resolveDomain($meta->getDomain());
}
public static function fromImport(
ShlinkUrl $url,
string $source,
bool $importShortCode,
?DomainResolverInterface $domainResolver = null
): self {
$meta = [
ShortUrlMetaInputFilter::DOMAIN => $url->domain(),
ShortUrlMetaInputFilter::VALIDATE_URL => false,
];
if ($importShortCode) {
$meta[ShortUrlMetaInputFilter::CUSTOM_SLUG] = $url->shortCode();
}
$instance = new self($url->longUrl(), ShortUrlMeta::fromRawData($meta), $domainResolver);
$instance->source = $source;
$instance->dateCreated = Chronos::instance($url->createdAt());
return $instance;
}
public function getLongUrl(): string
{
return $this->longUrl;

View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Importer;
use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Domain\Resolver\DomainResolverInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Util\TagManagerTrait;
use Shlinkio\Shlink\Importer\ImportedLinksProcessorInterface;
use Shlinkio\Shlink\Importer\Model\ShlinkUrl;
class ImportedLinksProcessor implements ImportedLinksProcessorInterface
{
use TagManagerTrait;
private EntityManagerInterface $em;
private DomainResolverInterface $domainResolver;
public function __construct(EntityManagerInterface $em, DomainResolverInterface $domainResolver)
{
$this->em = $em;
$this->domainResolver = $domainResolver;
}
/**
* @param ShlinkUrl[] $shlinkUrls
*/
public function process(iterable $shlinkUrls, string $source, array $params): void
{
$importShortCodes = $params['import_short_codes'];
$count = 0;
$persistBlock = 100;
foreach ($shlinkUrls as $url) {
$count++;
$shortUrl = ShortUrl::fromImport($url, $source, $importShortCodes, $this->domainResolver);
$shortUrl->setTags($this->tagNamesToEntities($this->em, $url->tags()));
// TODO Handle errors while creating short URLs, to avoid making the whole process fail
$this->em->persist($shortUrl);
// Flush and clear after X iterations
if ($count % $persistBlock === 0) {
$this->em->flush();
$this->em->clear();
}
}
$this->em->flush();
$this->em->clear();
}
}