Skip to content

PublishItemsTask is not scoped to draft items #488

@markbrawnfisherpaykel

Description

@markbrawnfisherpaykel

Module version(s) affected

5.3.*

Description

We have a GraphQL endpoint that we use for running tasks using an external scheduler.

PublishItemsTask runs fine through /dev/tasks`, but when running outside of this, the following line fails:

$item = DataObject::get_by_id('Page', $root);

It fails to fetch draft items because it is not inherently scoped to Versioned::DRAFT.

It feels like the publish task should take some responsibility for this, given that if reading mode is not set to DRAFT, it will always fail to find any items to process.

How to reproduce

  1. First create a draft page with a scheduled publish data.

  2. GraphQL

namespace D6\GraphQL {

	use GraphQL\Type\Definition\ResolveInfo;
	use GraphQL\Type\Definition\Type;
	use Psr\Log\LoggerInterface;
	use SilverStripe\Control\Controller;
	use SilverStripe\Core\ClassInfo;
	use SilverStripe\Core\Environment;
	use SilverStripe\Core\Injector\Injector;
	use SilverStripe\Dev\BuildTask;
	use SilverStripe\GraphQL\OperationResolver;
	use SilverStripe\GraphQL\QueryCreator;
	use SilverStripe\ORM\ArrayList;
	use SilverStripe\Security\IdentityStore;
	use SilverStripe\Security\Member;
	use SilverStripe\View\ArrayData;
	use SilverStripe\Control\CLIRequestBuilder;
	use SilverStripe\Dev\MigrationTask;
	use SilverStripe\Dev\Tasks\MigrateFileTask;

	/**
	 * Provides a graphQL query to run tasks (authentication omitted)
	 */
	class RunTask
	{
		public static function resolve($object, array $args, $context, ResolveInfo $info)
		{
			$taskInstance = null;
			$classes = ClassInfo::subclassesFor(BuildTask::class);
			foreach ($classes as $class) {
				$task = Injector::inst()->create($class);
				if ($task->config()->segment === $args['Task']) {
					$taskInstance = $task;
					break;
				}
			}
			if (!$taskInstance) throw new \Exception('Task "' . $args['Task'] . '" not found');
			ob_start();
			$request = CLIRequestBuilder::createFromEnvironment();
			$taskInstance->run($request);
			return ob_get_clean();
		}
	}
}
  1. GraphQL Config
---
after: '*'
---
SilverStripe\Control\Director:
  rules:
    'graphql': '%$SilverStripe\GraphQL\Controller.default'

SilverStripe\GraphQL\Schema\Schema:
  schemas:
    default:
      queries:
        'runTask(Task: String!)':
          type: String
          resolver: ['D6\GraphQL\RunTask', 'resolve']
  1. Call with:
query {
    runTask(Task: "ProcessJobQueueTask")
}

Possible Solution

// From Tasks/PublishItemsTask.php -> run($request)
$originalMode = Versioned::get_reading_mode();
Versioned::set_reading_mode('Stage', Versioned::DRAFT);
$item = DataObject::get_by_id('Page', $root);
if ($item && $item->exists()) {
    $job = new PublishItemsJob($root);
    singleton('Symbiote\\QueuedJobs\\Services\\QueuedJobService')->queueJob($job);
}
Versioned::set_reading_mode($originalMode);

Additional Context

No response

Validations

  • Check that there isn't already an issue that reports the same bug
  • Double check that your reproduction steps work in a fresh installation of silverstripe/installer (with any code examples you've provided)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions