Skip to content

Commit

Permalink
Implements console action 'update-crawler'
Browse files Browse the repository at this point in the history
(refs #14)
  • Loading branch information
TiSiE committed Oct 17, 2018
1 parent 2ffcdbc commit fe52632
Show file tree
Hide file tree
Showing 13 changed files with 1,372 additions and 60 deletions.
33 changes: 29 additions & 4 deletions config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
'factories' => [
'SimpleImport/ConsoleController' => Factory\Controller\ConsoleControllerFactory::class,
Controller\DeleteCrawlerConsoleController::class => Factory\Controller\DeleteCrawlerConsoleControllerFactory::class,
Controller\UpdateCrawlerConsoleController::class => Factory\Controller\UpdateCrawlerConsoleControllerFactory::class,
]
],
'controller_plugins' => [
Expand Down Expand Up @@ -88,8 +89,26 @@
],
],
],
]
]
'simpleimport-info' => [
'options' => [
'route' => 'simpleimport info [--id] [<name>]',
'defaults' => [
'controller' => Controller\UpdateCrawlerConsoleController::class,
'action' => 'index'
],
],
],
'simpleimport-update-crawler' => [
'options' => [
'route' => 'simpleimport update-crawler [--id] <name> [--rename=] [--feed-uri=] [--rundelay=] [--type=] [--jobInitialState=] [--organization=]',
'defaults' => [
'controller' => Controller\UpdateCrawlerConsoleController::class,
'action' => 'update'
],
],
],
],
],
],
'log' => [
'SimpleImport/Log' => [
Expand All @@ -108,11 +127,17 @@
InputFilter\CrawlerInputFilter::class => InvokableFactory::class
]
],
'filters' => [
'factories' => [
Filter\IdToEntity::class => Filter\IdToEntityFactory::class,
],
],
'validators' => [
'factories' => [
'SimpleImportOrganizationExists' => Factory\Validator\OrganizationExistsFactory::class,
Validator\CrawlerOptions::class => InvokableFactory::class
]
Validator\CrawlerOptions::class => InvokableFactory::class,
Validator\EntityExists::class => InvokableFactory::class,
],
],
'simple_import_crawler_processor_manager' => [
'factories' => [
Expand Down
161 changes: 161 additions & 0 deletions src/Controller/UpdateCrawlerConsoleController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php
/**
* YAWIK SimpleImport
*
* @filesource
* @license MIT
* @copyright 2013 - 2018 Cross Solution <http://cross-solution.de>
*/

/** */
namespace SimpleImport\Controller;

use SimpleImport\InputFilter\CrawlerInputFilter;
use Zend\Console\ColorInterface;
use Zend\InputFilter\InputFilter;
use Zend\Mvc\Console\Controller\AbstractConsoleController;

/**
* Update crawler configuration or displays crawler information.
*
* @author Mathias Gelhausen <gelhausen@cross-solution.de>
*/
class UpdateCrawlerConsoleController extends AbstractConsoleController
{
/**
* @var CrawlerInputFilter
*/
private $inputFilter;

/**
* @param CrawlerInputFilter $inputFilter
*
* @return self
*/
public function setInputFilter(CrawlerInputFilter $inputFilter)
{
$this->inputFilter = $inputFilter;

return $this;
}

/**
* displays list of crawlers or information about one crawler
*
* @return string|null
*/
public function indexAction()
{
/* @var \SimpleImport\Controller\Plugin\LoadCrawler $loader */

$loader = $this->plugin('siLoadCrawler');

if ($this->params('name')) {
$crawler = $loader();

return $this->info($crawler);
}

$set = $loader->loadAll();

echo PHP_EOL;
foreach ($set as $crawler) {
printf("%'.-40s (%s)" . PHP_EOL, $crawler->getName(), $crawler->getId());
}
}

/**
* generates cralwer information message.
*
* @param \SimpleImport\Entity\Crawler $crawler
*
* @return string
*/
private function info(\SimpleImport\Entity\Crawler $crawler)
{
return sprintf(<<<EOF
Name: %s (%s) [%s]
Organization: %s (%s)
Feed-URI: %s
Run delay: %s
Jobs initial state: %s
Date last run: %s
EOF
, $crawler->getName(), $crawler->getId(), $crawler->getType(),
$crawler->getOrganization()->getOrganizationName()->getName(),
$crawler->getOrganization()->getId(),
$crawler->getFeedUri(),
$crawler->getRunDelay(),
$crawler->getOptions()->getInitialState(),
$crawler->getDateLastRun()->format('d.m.Y H:i:s')
);

}


/**
* update the configuration of a crawler
*
* @return string
*/
public function updateAction()
{
/* @var \SimpleImport\Entity\Crawler $crawler */

$loader = $this->plugin('siLoadCrawler');
$crawler = $loader();
$values = $this->validateInput($crawler);
$console = $this->getConsole();

$crawler->setName($values['name']);
/** @noinspection PhpParamsInspection */
$crawler->setOrganization($values['organization']);
$crawler->setFeedUri($values['feedUri']);
$crawler->setRunDelay((int) $values['runDelay']);
$crawler->setType($values['type']);
$crawler->setOptionsFromArray((array) $values['options']);

$loader->store($crawler);

$console->writeLine('Crawler updated.', ColorInterface::GREEN);
return $this->info($crawler);
}

/**
* Validates rhe command line arguments.
*
* @param \SimpleImport\Entity\Crawler $crawler
*
* @return array
* @throws \RuntimeException if validation fails.
*/
private function validateInput(\SimpleImport\Entity\Crawler $crawler)
{
$params = $this->plugin('params');

$this->inputFilter->setData([
'name' => $params('rename', $crawler->getName()),
'feedUri' => $params('feed-uri', $crawler->getFeedUri()),
'organization' => $params('organization', $crawler->getOrganization()),
'runDelay' => $params('rundelay', $crawler->getRunDelay()),
'type' => $params('type', $crawler->getType()),
'options' => ['initialState' => $params('jobInitialState', $crawler->getOptions()->getInitialState())]
]);

if (!$this->inputFilter->isValid()) {
$message = 'Invalid parameters!' . PHP_EOL . PHP_EOL;
foreach ($this->inputFilter->getMessages() as $name => $messages) {
$message .= sprintf(' - %s: %s', $name, join(', ', $messages)) . PHP_EOL;
}

throw new \RuntimeException($message);
}

$values = array_filter($this->inputFilter->getValues(), function($i) { return !empty($i); });
return $values;
}

}
53 changes: 53 additions & 0 deletions src/Factory/Controller/UpdateCrawlerConsoleControllerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* YAWIK
*
* @filesource
* @license MIT
* @copyright 2013 - 2018 Cross Solution <http://cross-solution.de>
*/

/** */
namespace SimpleImport\Factory\Controller;

use SimpleImport\Controller\UpdateCrawlerConsoleController;
use Interop\Container\ContainerInterface;
use SimpleImport\InputFilter\CrawlerInputFilter;
use Zend\ServiceManager\Factory\FactoryInterface;

/**
* Factory for \SimpleImport\Controller\UpdateCrawlerConsoleController
*
* @author Mathias Gelhausen <gelhausen@cross-solution.de>
* @todo write test
*/
class UpdateCrawlerConsoleControllerFactory implements FactoryInterface
{

/**
* @param ContainerInterface $container
* @param string $requestedName
* @param array|null $options
*
* @return UpdateCrawlerConsoleController
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
/* @var CrawlerInputFilter $filter
* @var \Zend\Router\RouteMatch $routeMatch
*/

$controller = new UpdateCrawlerConsoleController();
$application = $container->get('Application');
$routeMatch = $application->getMvcEvent()->getRouteMatch();

if ('index' != $routeMatch->getParam('action')) {
$filters = $container->get('InputFilterManager');
$filter = $filters->get(CrawlerInputFilter::class);

$controller->setInputFilter($filter);
}

return $controller;
}
}
120 changes: 120 additions & 0 deletions src/Filter/IdToEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php
/**
* YAWIK
*
* @filesource
* @license MIT
* @copyright 2013 - 2018 Cross Solution <http://cross-solution.de>
*/

/** */
namespace SimpleImport\Filter;

use Doctrine\ODM\MongoDB\DocumentRepository;
use Zend\Filter\FilterInterface;

/**
* Filter to load an entity by its id.
*
* @author Mathias Gelhausen <gelhausen@cross-solution.de>
*/
class IdToEntity implements FilterInterface
{
/**
* @var DocumentRepository
*/
private $repository;

/**
* Custom value to return if no entity is found.
*
* @var mixed
*/
private $notFoundValue;

/**
* IdToEntity constructor.
*
* @param DocumentRepository $repository
*/
public function __construct(DocumentRepository $repository)
{
$this->repository = $repository;
}

/**
* Allows direct invokation.
*
* Proxies to {@łink filter()}
*
* @param mixed $value
*
* @return mixed|null
* @see filter
*/
public function __invoke($value)
{
return $this->filter($value);
}

/**
* @param mixed $notFoundValue
*
* @return self
*/
public function setNotFoundValue($notFoundValue)
{
$this->notFoundValue = $notFoundValue;

return $this;
}

/**
* @param $value
*
* @return mixed
*/
private function getNotFoundValue($value)
{
return $this->notFoundValue ?: $value;
}

/**
* Filters an id to an entity instance.
*
* If empty($value) is true, returns null.
*
* The id can be given as a string or as an instance of \MongoId.
* If an entity is passed, and it is of the type managed by {@link repository}, it is
* returned as is.
*
* If no entity with the given Id is found, the {@link notFoundValue} is returned
* which defaults to $value
*
* If $value is not an entity that {@link repository} manages, and $value is not a string
* or an instance of \MongoId, an exception is thrown.
*
* @param mixed $value
*
* @return mixed|null|object
* @throws \InvalidArgumentException
*/
public function filter($value)
{
if (empty($value)) { return null; }

if (is_string($value) || $value instanceOf \MongoId) {
return $this->repository->find($value) ?: $this->getNotFoundValue($value);
}

if (!is_a($value, $this->repository->getDocumentName())) {
throw new \InvalidArgumentException(sprintf(
'Value must either be a string or an instance of \MongoId or %s',
$this->repository->getDocumentName())
);
}

return $value;
}

}
Loading

0 comments on commit fe52632

Please sign in to comment.