See Release Notes
Long Term Support Release
<?php namespace PhpOffice\PhpSpreadsheet\Worksheet; use PhpOffice\PhpSpreadsheet\Shared\PasswordHasher; class Protection {> const ALGORITHM_MD2 = 'MD2'; /** > const ALGORITHM_MD4 = 'MD4'; * Sheet. > const ALGORITHM_MD5 = 'MD5'; * > const ALGORITHM_SHA_1 = 'SHA-1'; * @var bool > const ALGORITHM_SHA_256 = 'SHA-256'; */ > const ALGORITHM_SHA_384 = 'SHA-384'; private $sheet = false; > const ALGORITHM_SHA_512 = 'SHA-512'; > const ALGORITHM_RIPEMD_128 = 'RIPEMD-128'; /** > const ALGORITHM_RIPEMD_160 = 'RIPEMD-160'; * Objects. > const ALGORITHM_WHIRLPOOL = 'WHIRLPOOL'; * >< * Sheet.> * Autofilters are locked when sheet is protected, default true.< * @var bool> * @var ?bool< private $sheet = false;> private $autoFilter;< * Objects.> * Deleting columns is locked when sheet is protected, default true.< * @var bool> * @var ?bool< private $objects = false;> private $deleteColumns;< * Scenarios.> * Deleting rows is locked when sheet is protected, default true.< * @var bool> * @var ?bool*/< private $scenarios = false;> private $deleteRows;/**< * Format cells.> * Formatting cells is locked when sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $formatCells = false;> private $formatCells;/**< * Format columns.> * Formatting columns is locked when sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $formatColumns = false;> private $formatColumns;/**< * Format rows.> * Formatting rows is locked when sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $formatRows = false;> private $formatRows;/**< * Insert columns.> * Inserting columns is locked when sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $insertColumns = false;> private $insertColumns;/**< * Insert rows.> * Inserting hyperlinks is locked when sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $insertRows = false;> private $insertHyperlinks;/**< * Insert hyperlinks.> * Inserting rows is locked when sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $insertHyperlinks = false;> private $insertRows;/**< * Delete columns.> * Objects are locked when sheet is protected, default false.*< * @var bool> * @var ?bool*/< private $deleteColumns = false;> private $objects;/**< * Delete rows.> * Pivot tables are locked when the sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $deleteRows = false;> private $pivotTables;/**< * Select locked cells.> * Scenarios are locked when sheet is protected, default false.*< * @var bool> * @var ?bool*/< private $selectLockedCells = false;> private $scenarios;/**< * Sort.> * Selection of locked cells is locked when sheet is protected, default false.*< * @var bool> * @var ?bool*/< private $sort = false;> private $selectLockedCells;/**< * AutoFilter.> * Selection of unlocked cells is locked when sheet is protected, default false.*< * @var bool> * @var ?bool*/< private $autoFilter = false;> private $selectUnlockedCells;/**< * Pivot tables.> * Sheet is locked when sheet is protected, default false.*< * @var bool> * @var ?bool*/< private $pivotTables = false;> private $sheet;/**< * Select unlocked cells.> * Sorting is locked when sheet is protected, default true.*< * @var bool> * @var ?bool*/< private $selectUnlockedCells = false;> private $sort;/**< * Password.> * Hashed password.* * @var string */ private $password = ''; /**> * Algorithm name. * Create a new Protection. > * */ > * @var string public function __construct() > */ { > private $algorithm = ''; } > > /** /** > * Salt value. * Is some sort of protection enabled? > * * > * @var string * @return bool > */ */ > private $salt = ''; public function isProtectionEnabled() > { > /** return $this->sheet || > * Spin count. $this->objects || > * $this->scenarios || > * @var int $this->formatCells || > */ $this->formatColumns || > private $spinCount = 10000; $this->formatRows || > $this->insertColumns || > /**< * < * @return bool< public function isProtectionEnabled()> public function isProtectionEnabled(): bool< return $this->sheet || < $this->objects || < $this->scenarios || < $this->formatCells || < $this->formatColumns || < $this->formatRows || < $this->insertColumns || < $this->insertRows || < $this->insertHyperlinks || < $this->deleteColumns || < $this->deleteRows || < $this->selectLockedCells || < $this->sort || < $this->autoFilter || < $this->pivotTables || < $this->selectUnlockedCells;> return > $this->password !== '' || > isset($this->sheet) || > isset($this->objects) || > isset($this->scenarios) || > isset($this->formatCells) || > isset($this->formatColumns) || > isset($this->formatRows) || > isset($this->insertColumns) || > isset($this->insertRows) || > isset($this->insertHyperlinks) || > isset($this->deleteColumns) || > isset($this->deleteRows) || > isset($this->selectLockedCells) || > isset($this->sort) || > isset($this->autoFilter) || > isset($this->pivotTables) || > isset($this->selectUnlockedCells);< /** < * Get Sheet. < * < * @return bool < */ < public function getSheet()> public function getSheet(): ?bool< /** < * Set Sheet. < * < * @param bool $pValue < * < * @return Protection < */ < public function setSheet($pValue)> public function setSheet(?bool $sheet): self< $this->sheet = $pValue;> $this->sheet = $sheet;< /** < * Get Objects. < * < * @return bool < */ < public function getObjects()> public function getObjects(): ?bool{ return $this->objects; }< /** < * Set Objects. < * < * @param bool $pValue < * < * @return Protection < */ < public function setObjects($pValue)> public function setObjects(?bool $objects): self{< $this->objects = $pValue;> $this->objects = $objects;return $this; }< /** < * Get Scenarios. < * < * @return bool < */ < public function getScenarios()> public function getScenarios(): ?bool{ return $this->scenarios; }< /** < * Set Scenarios. < * < * @param bool $pValue < * < * @return Protection < */ < public function setScenarios($pValue)> public function setScenarios(?bool $scenarios): self{< $this->scenarios = $pValue;> $this->scenarios = $scenarios;return $this; }< /** < * Get FormatCells. < * < * @return bool < */ < public function getFormatCells()> public function getFormatCells(): ?bool{ return $this->formatCells; }< /** < * Set FormatCells. < * < * @param bool $pValue < * < * @return Protection < */ < public function setFormatCells($pValue)> public function setFormatCells(?bool $formatCells): self{< $this->formatCells = $pValue;> $this->formatCells = $formatCells;return $this; }< /** < * Get FormatColumns. < * < * @return bool < */ < public function getFormatColumns()> public function getFormatColumns(): ?bool{ return $this->formatColumns; }< /** < * Set FormatColumns. < * < * @param bool $pValue < * < * @return Protection < */ < public function setFormatColumns($pValue)> public function setFormatColumns(?bool $formatColumns): self{< $this->formatColumns = $pValue;> $this->formatColumns = $formatColumns;return $this; }< /** < * Get FormatRows. < * < * @return bool < */ < public function getFormatRows()> public function getFormatRows(): ?bool{ return $this->formatRows; }< /** < * Set FormatRows. < * < * @param bool $pValue < * < * @return Protection < */ < public function setFormatRows($pValue)> public function setFormatRows(?bool $formatRows): self{< $this->formatRows = $pValue;> $this->formatRows = $formatRows;return $this; }< /** < * Get InsertColumns. < * < * @return bool < */ < public function getInsertColumns()> public function getInsertColumns(): ?bool{ return $this->insertColumns; }< /** < * Set InsertColumns. < * < * @param bool $pValue < * < * @return Protection < */ < public function setInsertColumns($pValue)> public function setInsertColumns(?bool $insertColumns): self{< $this->insertColumns = $pValue;> $this->insertColumns = $insertColumns;return $this; }< /** < * Get InsertRows. < * < * @return bool < */ < public function getInsertRows()> public function getInsertRows(): ?bool{ return $this->insertRows; }< /** < * Set InsertRows. < * < * @param bool $pValue < * < * @return Protection < */ < public function setInsertRows($pValue)> public function setInsertRows(?bool $insertRows): self{< $this->insertRows = $pValue;> $this->insertRows = $insertRows;return $this; }< /** < * Get InsertHyperlinks. < * < * @return bool < */ < public function getInsertHyperlinks()> public function getInsertHyperlinks(): ?bool{ return $this->insertHyperlinks; }< /** < * Set InsertHyperlinks. < * < * @param bool $pValue < * < * @return Protection < */ < public function setInsertHyperlinks($pValue)> public function setInsertHyperlinks(?bool $insertHyperLinks): self{< $this->insertHyperlinks = $pValue;> $this->insertHyperlinks = $insertHyperLinks;return $this; }< /** < * Get DeleteColumns. < * < * @return bool < */ < public function getDeleteColumns()> public function getDeleteColumns(): ?bool{ return $this->deleteColumns; }< /** < * Set DeleteColumns. < * < * @param bool $pValue < * < * @return Protection < */ < public function setDeleteColumns($pValue)> public function setDeleteColumns(?bool $deleteColumns): self{< $this->deleteColumns = $pValue;> $this->deleteColumns = $deleteColumns;return $this; }< /** < * Get DeleteRows. < * < * @return bool < */ < public function getDeleteRows()> public function getDeleteRows(): ?bool{ return $this->deleteRows; }< /** < * Set DeleteRows. < * < * @param bool $pValue < * < * @return Protection < */ < public function setDeleteRows($pValue)> public function setDeleteRows(?bool $deleteRows): self{< $this->deleteRows = $pValue;> $this->deleteRows = $deleteRows;return $this; }< /** < * Get SelectLockedCells. < * < * @return bool < */ < public function getSelectLockedCells()> public function getSelectLockedCells(): ?bool{ return $this->selectLockedCells; }< /** < * Set SelectLockedCells. < * < * @param bool $pValue < * < * @return Protection < */ < public function setSelectLockedCells($pValue)> public function setSelectLockedCells(?bool $selectLockedCells): self{< $this->selectLockedCells = $pValue;> $this->selectLockedCells = $selectLockedCells;return $this; }< /** < * Get Sort. < * < * @return bool < */ < public function getSort()> public function getSort(): ?bool{ return $this->sort; }< /** < * Set Sort. < * < * @param bool $pValue < * < * @return Protection < */ < public function setSort($pValue)> public function setSort(?bool $sort): self{< $this->sort = $pValue;> $this->sort = $sort; > > return $this; > } > > public function getAutoFilter(): ?bool > { > return $this->autoFilter; > } > > public function setAutoFilter(?bool $autoFilter): self > { > $this->autoFilter = $autoFilter; > > return $this; > } > > public function getPivotTables(): ?bool > { > return $this->pivotTables; > } > > public function setPivotTables(?bool $pivotTables): self > { > $this->pivotTables = $pivotTables; > > return $this; > } > > public function getSelectUnlockedCells(): ?bool > { > return $this->selectUnlockedCells; > } > > public function setSelectUnlockedCells(?bool $selectUnlockedCells): self > { > $this->selectUnlockedCells = $selectUnlockedCells;return $this; } /**< * Get AutoFilter.> * Get hashed password.*< * @return bool> * @return string*/< public function getAutoFilter()> public function getPassword(){< return $this->autoFilter;> return $this->password;} /**< * Set AutoFilter.> * Set Password.*< * @param bool $pValue> * @param string $password > * @param bool $alreadyHashed If the password has already been hashed, set this to true*< * @return Protection> * @return $this*/< public function setAutoFilter($pValue)> public function setPassword($password, $alreadyHashed = false){< $this->autoFilter = $pValue;> if (!$alreadyHashed) { > $salt = $this->generateSalt(); > $this->setSalt($salt); > $password = PasswordHasher::hashPassword($password, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount()); > } > > $this->password = $password;return $this; }> public function setHashValue(string $password): self /** > { * Get PivotTables. > return $this->setPassword($password, true); * > } * @return bool >< * Get PivotTables. < * < * @return bool> * Create a pseudorandom string.< public function getPivotTables()> private function generateSalt(): string< return $this->pivotTables;> return base64_encode(random_bytes(16));/**< * Set PivotTables. < * < * @param bool $pValue < * < * @return Protection> * Get algorithm name.*/< public function setPivotTables($pValue)> public function getAlgorithm(): string{< $this->pivotTables = $pValue; < < return $this;> return $this->algorithm;} /**< * Get SelectUnlockedCells. < * < * @return bool> * Set algorithm name.*/< public function getSelectUnlockedCells()> public function setAlgorithm(string $algorithm): self{< return $this->selectUnlockedCells;> return $this->setAlgorithmName($algorithm);} /**< * Set SelectUnlockedCells. < * < * @param bool $pValue < * < * @return Protection> * Set algorithm name.*/< public function setSelectUnlockedCells($pValue)> public function setAlgorithmName(string $algorithm): self{< $this->selectUnlockedCells = $pValue;> $this->algorithm = $algorithm; > > return $this; > } > > public function getSalt(): string > { > return $this->salt; > } > > public function setSalt(string $salt): self > { > return $this->setSaltValue($salt); > } > > public function setSaltValue(string $salt): self > { > $this->salt = $salt;return $this; } /**< * Get Password (hashed). < * < * @return string> * Get spin count.*/< public function getPassword()> public function getSpinCount(): int{< return $this->password;> return $this->spinCount;} /**< * Set Password. < * < * @param string $pValue < * @param bool $pAlreadyHashed If the password has already been hashed, set this to true < * < * @return Protection> * Set spin count.*/< public function setPassword($pValue, $pAlreadyHashed = false)> public function setSpinCount(int $spinCount): self{< if (!$pAlreadyHashed) { < $pValue = PasswordHasher::hashPassword($pValue); < } < $this->password = $pValue;> $this->spinCount = $spinCount;return $this;> } } > > /** /** > * Verify that the given non-hashed password can "unlock" the protection. * Implement PHP __clone to create a deep clone, not just a shallow copy. > */ */ > public function verify(string $password): bool public function __clone() > { { > if ($this->password === '') { $vars = get_object_vars($this); > return true; foreach ($vars as $key => $value) { > } if (is_object($value)) { > $this->$key = clone $value; > $hash = PasswordHasher::hashPassword($password, $this->getAlgorithm(), $this->getSalt(), $this->getSpinCount()); } else { > $this->$key = $value; > return $this->getPassword() === $hash;} } } }