ype(): string { return $this->getExecutionInfo()->getType(); } /** * Detail about the creation context (e.g. the schedule name) * * @return ?string */ public function getExecutionSource(): ?string { return $this->getExecutionInfo()->getSource(); } /** * Free-form note on why the backup was created, as resolved at creation * * @return ?string */ public function getExecutionReason(): ?string { return $this->getExecutionInfo()->getReason(); } /** * Complete execution metadata. The fallback initializes packages stored * before execution metadata was introduced. * * @return PackageExecutionInfo */ public function getExecutionInfo(): PackageExecutionInfo { if ($this->execInfo === null) { $this->execInfo = new PackageExecutionInfo(static::DEFAULT_EXECUTION_TYPE); } return $this->execInfo; } /** * The immutable build configuration, or null when the backup hasn't * started yet (see freezeBuildOptions()) * * @return ?PackageBuildOptions */ public function getBuildOptions(): ?PackageBuildOptions { return $this->buildOptions; } /** * The immutable build configuration, the single source of truth of the * build. Callable only after the backup started: a build flow reaching * this point without the gate having frozen the options is a bug. * * @return PackageBuildOptions */ public function requireBuildOptions(): PackageBuildOptions { if ($this->buildOptions === null) { throw new DupliException( 'Package build options not frozen: the pre-backup gate did not run for this package.', DupliException::CODE_ERROR, __('The backup could not start because its configuration was not initialized. Please try again.', 'duplicator') ); } return $this->buildOptions; } /** * Freeze the resolved build configuration into the package. * * Called by OptionsManager::validatePackageConfig() on the one-time gate * pass that runs when the backup starts. From this moment the frozen * options are the single source of truth of the build: the dependent * state set provisionally at construction (archive format and file name, * database mode and its descriptor copy, zip thread mode, baked build progress * engine) is aligned * here and later changes to the global settings never affect the build. * A package already frozen is left untouched. * * @param PackageBuildOptions $buildOptions Resolved build configuration * * @return void */ public function freezeBuildOptions(PackageBuildOptions $buildOptions): void { if ($this->buildOptions !== null) { return; } $this->buildOptions = $buildOptions; $this->Archive->setFormatFromEngine($this->buildOptions->getArchiveEngine()); $this->Database->DBMode = $this->buildOptions->getDbBuildMode(); $this->Database->info->buildMode = $this->buildOptions->getDbBuildMode(); $this->ziparchive_mode = $this->buildOptions->getZipArchiveMode(); $this->build_progress->setBuildMode( $this->buildOptions->getArchiveEngine(), $this->buildOptions->isCompressionEnabled() ); } /** * Validates the inputs from the UI for correct data input * * @return InputValidator */ public function validateInputs() { $validator = new InputValidator(); if ($this->Archive->FilterOn) { $validator->explodeFilterCustom( $this->Archive->FilterDirs, ';', InputValidator::FILTER_VALIDATE_FOLDER_WITH_COMMENT, [ 'valkey' => 'FilterDirs', 'errmsg' => __( 'Directory: %1$s is an invalid path. Please remove the value from the Archive > Files Tab > Folders input box and apply only valid paths.', 'duplicator' ), ] ); $validator->explodeFilterCustom( $this->Archive->FilterExts, ';', InputValidator::FILTER_VALIDATE_FILE_EXT, [ 'valkey' => 'FilterExts', 'errmsg' => __( 'File extension: %1$s is an invalid extension name. Please remove the value from the Archive > Files Tab > File Extensions input box and apply only valid extensions. For example \'jpg\'', 'duplicator' ), ] ); $validator->explodeFilterCustom( $this->Archive->FilterFiles, ';', InputValidator::FILTER_VALIDATE_FILE_WITH_COMMENT, [ 'valkey' => 'FilterFiles', 'errmsg' => __( 'File: %1$s is an invalid file name. Please remove the value from the Archive > Files Tab > Files input box and apply only valid file names.', 'duplicator' ), ] ); } //FILTER_VALIDATE_DOMAIN throws notice message on PHP 5.6 if (defined('FILTER_VALIDATE_DOMAIN')) { // phpcs:ignore PHPCompatibility.Constants.NewConstants.filter_validate_domainFound $validator->filterVar($this->Installer->OptsDBHost, FILTER_VALIDATE_DOMAIN, [ 'valkey' => 'OptsDBHost', 'errmsg' => __('MySQL Server Host: %1$s isn\'t a valid host', 'duplicator'), 'acc_vals' => [ '', 'localhost', ], ]); } return $validator; } /** * Get created date * * @return string */ public function getCreated(): string { return $this->created; } /** * Get whether this backup uses client-side kickoff. * * @return bool True if client-side kickoff is needed, false if server can self-request */ public function isClientSideKickoff(): bool { return ClientSideKick::isClientSideKickoffMode(); } }