function StageBase::create
Copies the active code base into the stage directory.
This will automatically claim the stage, so external code does NOT need to call ::claim(). However, if it was created during another request, the stage must be claimed before operations can be performed on it.
Parameters
int|null $timeout: (optional) How long to allow the file copying operation to run before timing out, in seconds, or NULL to never time out. Defaults to 300 seconds.
Return value
string Unique ID for the stage, which can be used to claim the stage before performing other operations on it. Calling code should store this ID for as long as the stage needs to exist.
Throws
\Drupal\package_manager\Exception\StageException Thrown if a stage directory already exists, or if an error occurs while creating the stage directory. In the latter situation, the stage directory will be destroyed.
See also
::claim()
File
-
core/
modules/ package_manager/ src/ StageBase.php, line 309
Class
- StageBase
- Creates and manages a stage directory in which to install or update code.
Namespace
Drupal\package_managerCode
public function create(?int $timeout = 300) : string {
$this->failureMarker
->assertNotExists();
if (!$this->isAvailable()) {
throw new StageException($this, 'Cannot create a new stage because one already exists.');
}
// Mark the stage as unavailable as early as possible, before dispatching
// the pre-create event. The idea is to prevent a race condition if the
// event subscribers take a while to finish, and two different users attempt
// to create a stage directory at around the same time. If an error occurs
// while the event is being processed, the stage is marked as available.
// @see ::dispatch()
// We specifically generate a random 32-character alphanumeric name in order
// to guarantee that the stage ID won't start with -, which could cause it
// to be interpreted as an option if it's used as a command-line argument.
// (For example, \Drupal\Component\Utility\Crypt::randomBytesBase64() would
// be vulnerable to this; the stage ID needs to be unique, but not
// cryptographically so.)
$id = (new Random())->name(32);
// Re-acquire the tempstore to ensure that the lock is written by whoever is
// actually logged in (or not) right now, since it's possible that the stage
// was instantiated (i.e., __construct() was called) by a different session,
// which would result in the lock having the wrong owner and the stage not
// being claimable by whoever is actually creating it.
$this->tempStore = $this->tempStoreFactory
->get('package_manager_stage');
// For the lock value, we use both the stage's class and its type in order
// to prevent a stage from being manipulated by two different classes during
// a single life cycle.
$this->tempStore
->set(static::TEMPSTORE_LOCK_KEY, [
$id,
static::class,
$this->getType(),
]);
$this->claim($id);
$active_dir = $this->pathFactory
->create($this->pathLocator
->getProjectRoot());
$stage_dir = $this->pathFactory
->create($this->getStageDirectory());
$excluded_paths = $this->getPathsToExclude();
$event = new PreCreateEvent($this, $excluded_paths);
// If an error occurs and we won't be able to create the stage, mark it as
// available.
$this->dispatch($event, [
$this,
'markAsAvailable',
]);
try {
$this->beginner
->begin($active_dir, $stage_dir, $excluded_paths, NULL, $timeout);
} catch (\Throwable $error) {
$this->destroy();
$this->rethrowAsStageException($error);
}
$this->dispatch(new PostCreateEvent($this));
return $id;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.