silverstripe-framework/src/Assets/Storage/DefaultAssetNameGenerator.php

171 lines
3.8 KiB
PHP

<?php
namespace SilverStripe\Assets\Storage;
use SilverStripe\Core\Config\Config;
/**
* Basic filename renamer
*/
class DefaultAssetNameGenerator implements AssetNameGenerator
{
/**
* A prefix for the version number added to an uploaded file
* when a file with the same name already exists.
* Example using no prefix: IMG001.jpg becomes IMG2.jpg
* Example using '-v' prefix: IMG001.jpg becomes IMG001-v2.jpg
*
* @config
* @var string
*/
private static $version_prefix = '-v';
/**
* Original filename
*
* @var string
*/
protected $filename;
/**
* Directory
*
* @var string
*/
protected $directory;
/**
* Name without extension or directory
*
* @var string
*/
protected $name;
/**
* Extension (including leading period)
*
* @var string
*/
protected $extension;
/**
* Next version number to suggest
*
* @var int
*/
protected $version;
/**
* Maximum number to suggest
*
* @var int
*/
protected $max = 100;
/**
* Number of digits to prefix with 0, if padding
*
* @var int
*/
protected $padding = 0;
/**
* First version
*
* @var int
*/
protected $first = null;
public function __construct($filename)
{
$this->filename = $filename;
$this->directory = ltrim(dirname($filename), '.');
$name = basename($this->filename);
// Note: Unlike normal extensions, we want to split at the first period, not the last.
if (($pos = strpos($name, '.')) !== false) {
$this->extension = substr($name, $pos);
$name = substr($name, 0, $pos);
} else {
$this->extension = null;
}
// Extract version prefix if already applied to this file
$this->padding = 0;
$pattern = '/^(?<name>[^\/]+?)' . preg_quote($this->getPrefix()) . '(?<version>[0-9]+)$/';
if (preg_match($pattern, $name, $matches)) {
$this->first = (int)$matches['version'];
$this->name = $matches['name'];
// Check if number is padded
if (strpos($matches['version'], '0') === 0) {
$this->padding = strlen($matches['version']);
}
} else {
$this->first = 1;
$this->name = $name;
}
$this->rewind();
}
/**
* Get numeric prefix
*
* @return string
*/
protected function getPrefix()
{
return Config::inst()->get(__CLASS__, 'version_prefix');
}
public function current()
{
$version = $this->version;
// Initially suggest original name
if ($version === $this->first) {
return $this->filename;
}
// If there are more than $this->max files we need a new scheme
if ($version >= $this->max + $this->first - 1) {
$version = substr(md5(time()), 0, 10);
} elseif ($this->padding) {
// Else, pad
$version = str_pad($version, $this->padding, '0', STR_PAD_LEFT);
}
// Build next name
$filename = $this->name . $this->getPrefix() . $version . $this->extension;
if ($this->directory) {
$filename = $this->directory . DIRECTORY_SEPARATOR . $filename;
}
return $filename;
}
public function key()
{
return $this->version - $this->first;
}
public function next()
{
$this->version++;
}
public function rewind()
{
$this->version = $this->first;
}
public function valid()
{
return $this->version < $this->max + $this->first;
}
public function getMaxTries()
{
return $this->max;
}
}