Skip to content

Commit

Permalink
Make use of code event listener instead of content type system
Browse files Browse the repository at this point in the history
  • Loading branch information
ticktackk committed Apr 4, 2019
1 parent 5ecdc7e commit 95fd312
Show file tree
Hide file tree
Showing 25 changed files with 614 additions and 245 deletions.
25 changes: 16 additions & 9 deletions upload/src/addons/TickTackk/Seeder/Cli/Command/Seeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ protected function configure() : void
{
$this
->setName('tck-seeder:seed')
->setDescription('Runs all the seeds to fill your forum with dummy data.')
->setDescription('Runs the seeds to fill your forum with dummy data.')
->addOption(
'content-type',
'seed',
't',
InputOption::VALUE_OPTIONAL,
'Run specific seed instead of all'
'Name of the specific seed which should be used for seeding.'
);
}

Expand All @@ -41,13 +41,20 @@ protected function execute(InputInterface $input, OutputInterface $output) : ? i
{
\XF::db()->logQueries(false);

/** @var \TickTackk\Seeder\Repository\Seed $seedRepo */
$seedRepo = \XF::app()->repository('TickTackk\Seeder:Seed');
$contentType = $input->getOption('content-type');
$orderedSeeds = $seedRepo->getOrderedSeeds(!empty($contentType) ? [$contentType] : null);
$seedNames = [];
$seedName = $input->getOption('seed');

$this->setupAndRunJob('tckSeeder' . (!empty($contentType) ? '_' . $contentType : ''), 'TickTackk\Seeder:Seed', [
'seeds' => $orderedSeeds
if ($seedName)
{
$seedNames = [$seedName];
}
else
{
\XF::fire('seed_list', [\XF::app(), &$seedNames]);
}

$this->setupAndRunJob('tckSeeder' . \count($seedNames) === 1 ? '_' . reset($seedNames) : '', 'TickTackk\Seeder:Seed', [
'seeds' => $seedNames
], $output);

return 0;
Expand Down
114 changes: 78 additions & 36 deletions upload/src/addons/TickTackk/Seeder/Job/Seed.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class Seed extends AbstractJob
protected $defaultData = [
'seeds' => [],
'currentSeed' => null,
'currentSeedPhrase' => null,
'seedStats' => []
];

Expand All @@ -37,76 +36,118 @@ public function run($maxRunTime): \XF\Job\JobResult
$this->data['currentSeed'] = reset($this->data['seeds']);
}

$currentSeed = $this->getCurrentSeed();
if (isset($this->data['seedStats'][$currentSeed]))
$currentSeedClass = $this->getCurrentSeedClass();
if (isset($this->data['seedStats'][$currentSeedClass]) && $this->getDoneForCurrentSeed() >= $this->getLimitForCurrentSeed())
{
if ($this->getDoneForCurrentSeed() >= $this->getLimitForCurrentSeed())
$currentSeedClass = $this->getNextSeed();
if ($currentSeedClass === null)
{
$currentSeed = $this->getNextSeed();
if ($currentSeed === null)
{
return $this->complete();
}

$this->data['currentSeed'] = $currentSeed;
return $this->complete();
}

$this->data['currentSeed'] = $currentSeedClass;
}

/** @var \TickTackk\Seeder\Repository\Seed $seedRepo */
$seedRepo = $this->app->repository('TickTackk\Seeder:Seed');
if ($seedHandler = $seedRepo->getSeedHandler($currentSeed))
$currentSeed = $this->getCurrentSeed();
if (!isset($this->data['seedStats'][$currentSeedClass]))
{
$this->data['currentSeedPhrase'] = $seedHandler->getContentTypePhrased(true)->render('raw');

if (!isset($this->data['seedStats'][$currentSeed]))
{
$this->data['seedStats'][$currentSeed] = [
'done' => 0,
'limit' => $seedHandler->getLimit()
];
}
$this->data['seedStats'][$currentSeedClass] = [
'done' => 0,
'limit' => $currentSeed->getLimit()
];
}

do
{
$seedHandler->run();
$this->bumpDoneForCurrentSeed();
do
{
$currentSeed->run();
$this->bumpDoneForCurrentSeed();

$hasSeededAll = $this->getDoneForCurrentSeed() >= $this->getLimitForCurrentSeed();
$timeRemaining = $maxRunTime - (microtime(true) - $startTime);
}
while (!$hasSeededAll && $timeRemaining >= 1);
$hasSeededAll = $this->getDoneForCurrentSeed() >= $this->getLimitForCurrentSeed();
$timeRemaining = $maxRunTime - (microtime(true) - $startTime);
}
while (!$hasSeededAll && $timeRemaining >= 1);

return $this->resume();
}

protected function bumpDoneForCurrentSeed(): void
{
$this->data['seedStats'][$this->getCurrentSeed()]['done']++;
$this->data['seedStats'][$this->getCurrentSeedClass()]['done']++;
}

/**
* @param string $seedName
*
* @return \TickTackk\Seeder\Seed\AbstractSeed
* @throws \Exception
*/
public function getSeed(string $seedName) : \TickTackk\Seeder\Seed\AbstractSeed
{
/** @var \TickTackk\Seeder\Repository\Seed $seedRepo */
$seedRepo = $this->app->repository('TickTackk\Seeder:Seed');
return $seedRepo->getSeedHandler($seedName);
}

/**
* @return \TickTackk\Seeder\Seed\AbstractSeed
* @throws \Exception
*/
public function getCurrentSeed() : \TickTackk\Seeder\Seed\AbstractSeed
{
return $this->getSeed($this->getCurrentSeedClass());
}

/**
* @return string
*/
protected function getCurrentSeed(): string
protected function getCurrentSeedClass(): string
{
return $this->data['currentSeed'] ?? '';
}

/**
* @return string
* @throws \Exception
*/
protected function getTitleForCurrentSeed() : string
{
$currentSeed = $this->getCurrentSeed();

$title = $currentSeed->getTitle();
if ($title instanceof \XF\Phrase)
{
$title = $title->render('raw');
}

return $title;
}

/**
* @return int
* @throws \Exception
*/
protected function getDoneForCurrentSeed(): int
{
return $this->data['seedStats'][$this->getCurrentSeed()]['done'] ?? 0;
$done = $this->data['seedStats'][$this->getCurrentSeedClass()]['done'] ?? 0;

$currentSeed = $this->getCurrentSeed();
$currentSeed->setDone($done);

return $currentSeed->getDone();
}

/**
* @return int
* @throws \Exception
*/
public function getLimitForCurrentSeed(): int
{
return $this->data['seedStats'][$this->getCurrentSeed()]['limit'] ?? 0;
$limit = $this->data['seedStats'][$this->getCurrentSeedClass()]['limit'] ?? 0;

$currentSeed = $this->getCurrentSeed();
$currentSeed->setLimit($limit);

return $currentSeed->getLimit();
}

/**
Expand All @@ -121,13 +162,14 @@ protected function getNextSeed(): ?string

/**
* @return string
* @throws \Exception
*/
public function getStatusMessage(): string
{
return sprintf(
'%s %s (%d/%d)...',
'Seeding...',
$this->data['currentSeedPhrase'],
$this->getTitleForCurrentSeed(),
$this->getDoneForCurrentSeed(),
$this->getLimitForCurrentSeed()
);
Expand Down
23 changes: 23 additions & 0 deletions upload/src/addons/TickTackk/Seeder/Listener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace TickTackk\Seeder;

/**
* Class Listener
*
* @package TickTackk\Seeder
*/
class Listener
{
/**
* @param \XF\Cli\App $app
* @param array $seeds
*/
public static function seedList(\XF\App $app, array &$seeds) : void
{
foreach (['User', 'Category', 'Forum', 'Page', 'Thread', 'Post', 'PostReactionContent'] AS $className)
{
$seeds[] = 'TickTackk\Seeder:' . $className;
}
}
}
85 changes: 8 additions & 77 deletions upload/src/addons/TickTackk/Seeder/Repository/Seed.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,89 +13,20 @@
class Seed extends Repository
{
/**
* @param string $type
* @param bool $throw
* @param string $seedName
*
* @return null|AbstractSeed
* @return AbstractSeed
* @throws \Exception
*/
public function getSeedHandler(string $type, bool $throw = false) :? AbstractSeed
public function getSeedHandler(string $seedName) : AbstractSeed
{
$handlerClass = $this->app()->getContentTypeFieldValue($type, 'seed_handler_class');
if (!$handlerClass)
$seedClass = \XF::stringToClass($seedName, '%s\Seed\%s');
if (!class_exists($seedClass))
{
if ($throw)
{
throw new \InvalidArgumentException("No Seed handler for '$type'");
}
return null;
throw new \InvalidArgumentException("Seed handler does not exist: $seedClass");
}

if (!class_exists($handlerClass))
{
if ($throw)
{
throw new \InvalidArgumentException("Seed handler for '$type' does not exist: $handlerClass");
}
return null;
}

$handlerClass = \XF::extendClass($handlerClass);
return new $handlerClass($this->app(), $type);
}

/**
* @param bool $throw
*
* @return AbstractSeed[]
* @throws \Exception
*/
public function getSeedHandlers($throw = false) : array
{
$handlers = [];

foreach (\XF::app()->getContentTypeField('seed_handler_class') AS $contentType => $handlerClass)
{
if ($handler = $this->getSeedHandler($contentType, $throw))
{
$handlers[$contentType] = $handler;
}
}

return $handlers;
}

/**
* @param array|null $contentTypes
* @return array
* @throws \Exception
*/
public function getOrderedSeeds(array $contentTypes = null)
{
$handlers = $this->getSeedHandlers();
$internalHandlerCollection = [];

foreach ($handlers AS $contentType => $handler)
{
if ($contentTypes === null || \in_array($contentType, $contentTypes, true))
{
$internalHandlerCollection[$handler->getRunOrder()][] = [
'contentType' => $contentType,
'handler' => $handler
];
}
}
ksort($internalHandlerCollection);

$finalHandlers = [];
foreach ($internalHandlerCollection AS $order => $internalHandler)
{
foreach ($internalHandler AS $data)
{
$finalHandlers[$order . '_' . $data['contentType']] = $data['contentType'];
}
}

return $finalHandlers;
$seedClass = \XF::extendClass($seedClass);
return new $seedClass($this->app());
}
}
15 changes: 4 additions & 11 deletions upload/src/addons/TickTackk/Seeder/Seed/AbstractNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,20 @@ protected function getRandomParentNode() :? \XF\Entity\AbstractNode
/**
* @return array
*/
protected function getNodeInput()
protected function getNodeInput() : array
{
$faker = $this->faker();
$parentNode = $this->getRandomParentNode();

$input = [
'parent_node_id' => 0,
return [
'parent_node_id' => $parentNode ? $parentNode->node_id : 0,
'title' => implode(' ', Lorem::words()),
'description' => $faker->paragraph,
'display_order' => $faker->randomNumber(),
'display_in_list' => true,
'style_id' => 0,
'navigation_id' => 'str',
];

if ($this->faker()->boolean)
{
$parentNode = $this->getRandomParentNode();
$input['parent_node_id'] = $parentNode->node_id;
}

return $input;
}

/**
Expand Down
Loading

0 comments on commit 95fd312

Please sign in to comment.