Ctrl K
ComunidadGuías…

engine/classes/ElggUpgrade.php

Rama 7.x · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<?php
/**
 * Upgrade object for upgrades that need to be tracked
 * and listed in the admin area.
 */

use Elgg\Exceptions\InvalidArgumentException as ElggInvalidArgumentException;
use Elgg\Exceptions\UnexpectedValueException as ElggUnexpectedValueException;
use Elgg\Traits\TimeUsing;
use Elgg\Upgrade\Batch;

/**
 * Represents an upgrade that runs outside the upgrade.php script
 *
 * @internal
 *
 * @property bool   $is_completed   Is the upgrade completed yet
 * @property int    $processed      Number of items processed
 * @property int    $offset         Offset for batch
 * @property int    $has_errors     Number of errors
 * @property int    $completed_time Time when the upgrade finished
 * @property int    $start_time     Time when the upgrade started
 * @property string $id             The ID of the upgrade
 * @property string $class          The class which will handle the upgrade
 */
class ElggUpgrade extends ElggObject {

	use TimeUsing;

	/**
	 * {@inheritdoc}
	 */
	public function initializeAttributes() {
		parent::initializeAttributes();
		
		$site = elgg_get_site_entity();
		
		$this->attributes['subtype'] = 'elgg_upgrade';
		$this->attributes['container_guid'] = $site->guid;
		$this->attributes['owner_guid'] = $site->guid;
		
		$this->offset = 0;
		$this->is_completed = false;
	}
	
	/**
	 * {@inheritdoc}
	 */
	public function getDisplayName(): string {
		$component = $this->getComponent();
		$version = $this->getVersion();
		
		return elgg_echo("{$component}:upgrade:{$version}:title");
	}

	/**
	 * Mark this upgrade as completed
	 *
	 * @return void
	 */
	public function setCompleted(): void {
		$this->setStartTime(); // to make sure a start time is present
		$this->setCompletedTime();
		$this->is_completed = true;

		elgg_trigger_event('complete', 'upgrade', $this);
	}

	/**
	 * Has this upgrade completed?
	 *
	 * @return bool
	 */
	public function isCompleted(): bool {
		return (bool) $this->is_completed;
	}
	
	/**
	 * Get the unique ID for the upgrade in the format <plugin_name>:<yyymmddhh>
	 *
	 * @return string|null
	 * @since 7.1
	 */
	public function getID(): ?string {
		return $this->id;
	}
	
	/**
	 * Get the component where the upgrade originated ('core' or a plugin ID)
	 *
	 * @return string|null
	 */
	public function getComponent(): ?string {
		if (!isset($this->id)) {
			return null;
		}
		
		$parts = explode(':', $this->id);
		
		return elgg_extract(0, $parts);
	}
	
	/**
	 * Get the version of the upgrade in the format <yyymmddhh>
	 *
	 * @return int|null
	 */
	public function getVersion(): ?int {
		if (!isset($this->id)) {
			return null;
		}
		
		$parts = explode(':', $this->id);
		
		return elgg_extract(1, $parts) ? (int) elgg_extract(1, $parts) : null;
	}

	/**
	 * Check if the upgrade should be run asynchronously
	 *
	 * @return bool
	 */
	public function isAsynchronous(): bool {
		return is_subclass_of($this->class, \Elgg\Upgrade\AsynchronousUpgrade::class);
	}

	/**
	 * Return instance of the class that processes the data
	 *
	 * @return Batch|false
	 */
	public function getBatch(): Batch|false {
		try {
			$batch = _elgg_services()->upgradeLocator->getBatch($this->class, $this);
		} catch (ElggInvalidArgumentException $ex) {
			// only report error if the upgrade still needs to run
			$loglevel = $this->isCompleted() ? \Psr\Log\LogLevel::INFO : \Psr\Log\LogLevel::ERROR;
			elgg_log($ex->getMessage(), $loglevel);
			
			return false;
		}

		// check version before shouldBeSkipped() so authors can get immediate feedback on an invalid batch.
		$version = $batch->getVersion();

		// Version must be in format yyyymmddnn
		if (preg_match('/^[0-9]{10}$/', $version) === 0) {
			elgg_log("Upgrade {$this->class} returned an invalid version: {$version}");
			return false;
		}

		return $batch;
	}

	/**
	 * Sets the timestamp for when the upgrade completed.
	 *
	 * @param null|int $time Timestamp when upgrade finished. Defaults to now
	 *
	 * @return void
	 */
	public function setCompletedTime(?int $time = null): void {
		$this->completed_time = $time ?? $this->getCurrentTime()->getTimestamp();
	}

	/**
	 * Gets the time when the upgrade completed.
	 *
	 * @return int
	 */
	public function getCompletedTime(): int {
		return (int) $this->completed_time;
	}
	
	/**
	 * Resets the update in order to be able to run it again
	 *
	 * @return void
	 */
	public function reset(): void {
		$this->is_completed = false;
		$this->offset = 0;
		
		unset($this->completed_time);
		unset($this->processed);
		unset($this->start_time);
	}
	
	/**
	 * Sets the timestamp for when the upgrade started.
	 * Once set it can't be altered unless the upgrade gets reset
	 *
	 * @param null|int $time Timestamp when upgrade started. Defaults to now
	 *
	 * @return void
	 */
	public function setStartTime(?int $time = null): void {
		if (isset($this->start_time)) {
			return;
		}
		
		$this->start_time = $time ?? $this->getCurrentTime()->getTimestamp();
	}
	
	/**
	 * Gets the time when the upgrade completed.
	 *
	 * @return int
	 */
	public function getStartTime(): int {
		return (int) $this->start_time;
	}
}