Upgrade to 4.0.0
This commit is contained in:
@@ -21,29 +21,49 @@ use Kirby\Uuid\Uuids;
|
||||
*/
|
||||
trait FileActions
|
||||
{
|
||||
protected function changeExtension(
|
||||
File $file,
|
||||
string|null $extension = null
|
||||
): File {
|
||||
if (
|
||||
$extension === null ||
|
||||
$extension === $file->extension()
|
||||
) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return $file->changeName($file->name(), false, $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the file without touching the extension
|
||||
* Renames the file (optionally also the extension).
|
||||
* The store is used to actually execute this.
|
||||
*
|
||||
* @param string $name
|
||||
* @param bool $sanitize
|
||||
* @return $this|static
|
||||
* @throws \Kirby\Exception\LogicException
|
||||
*/
|
||||
public function changeName(string $name, bool $sanitize = true)
|
||||
{
|
||||
public function changeName(
|
||||
string $name,
|
||||
bool $sanitize = true,
|
||||
string|null $extension = null
|
||||
): static {
|
||||
if ($sanitize === true) {
|
||||
$name = F::safeName($name);
|
||||
}
|
||||
|
||||
// if no extension is passed, make sure to maintain current one
|
||||
$extension ??= $this->extension();
|
||||
|
||||
// don't rename if not necessary
|
||||
if ($name === $this->name()) {
|
||||
if (
|
||||
$name === $this->name() &&
|
||||
$extension === $this->extension()
|
||||
) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->commit('changeName', ['file' => $this, 'name' => $name], function ($oldFile, $name) {
|
||||
return $this->commit('changeName', ['file' => $this, 'name' => $name, 'extension' => $extension], function ($oldFile, $name, $extension) {
|
||||
$newFile = $oldFile->clone([
|
||||
'filename' => $name . '.' . $oldFile->extension(),
|
||||
'filename' => $name . '.' . $extension,
|
||||
]);
|
||||
|
||||
// remove all public versions, lock and clear UUID cache
|
||||
@@ -60,16 +80,11 @@ trait FileActions
|
||||
// rename the main file
|
||||
F::move($oldFile->root(), $newFile->root());
|
||||
|
||||
if ($newFile->kirby()->multilang() === true) {
|
||||
foreach ($newFile->translations() as $translation) {
|
||||
$translationCode = $translation->code();
|
||||
|
||||
// rename the content file
|
||||
F::move($oldFile->contentFile($translationCode), $newFile->contentFile($translationCode));
|
||||
}
|
||||
} else {
|
||||
// rename the content file
|
||||
F::move($oldFile->contentFile(), $newFile->contentFile());
|
||||
// move the content storage versions
|
||||
foreach ($oldFile->storage()->all() as $version => $lang) {
|
||||
$content = $oldFile->storage()->read($version, $lang);
|
||||
$oldFile->storage()->delete($version, $lang);
|
||||
$newFile->storage()->create($version, $lang, $content);
|
||||
}
|
||||
|
||||
// update collections
|
||||
@@ -82,11 +97,8 @@ trait FileActions
|
||||
|
||||
/**
|
||||
* Changes the file's sorting number in the meta file
|
||||
*
|
||||
* @param int $sort
|
||||
* @return static
|
||||
*/
|
||||
public function changeSort(int $sort)
|
||||
public function changeSort(int $sort): static
|
||||
{
|
||||
return $this->commit(
|
||||
'changeSort',
|
||||
@@ -95,6 +107,40 @@ trait FileActions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this|static
|
||||
*/
|
||||
public function changeTemplate(string|null $template): static
|
||||
{
|
||||
if ($template === $this->template()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$arguments = [
|
||||
'file' => $this,
|
||||
'template' => $template ?? 'default'
|
||||
];
|
||||
|
||||
return $this->commit('changeTemplate', $arguments, function ($oldFile, $template) {
|
||||
// convert to new template/blueprint incl. content
|
||||
$file = $oldFile->convertTo($template);
|
||||
|
||||
// update template, prefer unset over writing `default`
|
||||
if ($template === 'default') {
|
||||
$template = null;
|
||||
}
|
||||
|
||||
$file = $file->update(['template' => $template]);
|
||||
|
||||
// rename and/or resize the file if configured by new blueprint
|
||||
$create = $file->blueprint()->create();
|
||||
$file = $file->changeExtension($file, $create['format'] ?? null);
|
||||
$file->manipulate($create);
|
||||
|
||||
return $file;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits a file action, by following these steps
|
||||
*
|
||||
@@ -103,14 +149,12 @@ trait FileActions
|
||||
* 3. commits the store action
|
||||
* 4. sends the after hook
|
||||
* 5. returns the result
|
||||
*
|
||||
* @param string $action
|
||||
* @param array $arguments
|
||||
* @param Closure $callback
|
||||
* @return mixed
|
||||
*/
|
||||
protected function commit(string $action, array $arguments, Closure $callback)
|
||||
{
|
||||
protected function commit(
|
||||
string $action,
|
||||
array $arguments,
|
||||
Closure $callback
|
||||
): mixed {
|
||||
$old = $this->hardcopy();
|
||||
$kirby = $this->kirby();
|
||||
$argumentValues = array_values($arguments);
|
||||
@@ -134,24 +178,19 @@ trait FileActions
|
||||
|
||||
/**
|
||||
* Copy the file to the given page
|
||||
*
|
||||
* @param \Kirby\Cms\Page $page
|
||||
* @return \Kirby\Cms\File
|
||||
*/
|
||||
public function copy(Page $page)
|
||||
public function copy(Page $page): static
|
||||
{
|
||||
F::copy($this->root(), $page->root() . '/' . $this->filename());
|
||||
$copy = $page->clone()->file($this->filename());
|
||||
|
||||
if ($this->kirby()->multilang() === true) {
|
||||
foreach ($this->kirby()->languages() as $language) {
|
||||
$contentFile = $this->contentFile($language->code());
|
||||
F::copy($contentFile, $page->root() . '/' . basename($contentFile));
|
||||
}
|
||||
} else {
|
||||
$contentFile = $this->contentFile();
|
||||
F::copy($contentFile, $page->root() . '/' . basename($contentFile));
|
||||
foreach ($this->storage()->all() as $version => $lang) {
|
||||
$content = $this->storage()->read($version, $lang);
|
||||
$copy->storage()->create($version, $lang, $content);
|
||||
}
|
||||
|
||||
// ensure the content is re-read after copying it
|
||||
// @todo find a more elegant way
|
||||
$copy = $page->clone()->file($this->filename());
|
||||
|
||||
// overwrite with new UUID (remove old, add new)
|
||||
@@ -168,13 +207,11 @@ trait FileActions
|
||||
* writing, so it can be replaced by any other
|
||||
* way of generating files.
|
||||
*
|
||||
* @param array $props
|
||||
* @param bool $move If set to `true`, the source will be deleted
|
||||
* @return static
|
||||
* @throws \Kirby\Exception\InvalidArgumentException
|
||||
* @throws \Kirby\Exception\LogicException
|
||||
*/
|
||||
public static function create(array $props, bool $move = false)
|
||||
public static function create(array $props, bool $move = false): File
|
||||
{
|
||||
if (isset($props['source'], $props['parent']) === false) {
|
||||
throw new InvalidArgumentException('Please provide the "source" and "parent" props for the File');
|
||||
@@ -204,9 +241,15 @@ trait FileActions
|
||||
// inject the content
|
||||
$file = $file->clone(['content' => $form->strings(true)]);
|
||||
|
||||
// if the format is different from the original,
|
||||
// we need to already rename it so that the correct file rules
|
||||
// are applied
|
||||
$create = $file->blueprint()->create();
|
||||
$file = $file->changeExtension($file, $create['format'] ?? null);
|
||||
|
||||
// run the hook
|
||||
$arguments = compact('file', 'upload');
|
||||
return $file->commit('create', $arguments, function ($file, $upload) use ($move) {
|
||||
return $file->commit('create', $arguments, function ($file, $upload) use ($create, $move) {
|
||||
// remove all public versions, lock and clear UUID cache
|
||||
$file->unpublish();
|
||||
|
||||
@@ -218,15 +261,15 @@ trait FileActions
|
||||
throw new LogicException('The file could not be created');
|
||||
}
|
||||
|
||||
// always create pages in the default language
|
||||
if ($file->kirby()->multilang() === true) {
|
||||
$languageCode = $file->kirby()->defaultLanguage()->code();
|
||||
} else {
|
||||
$languageCode = null;
|
||||
}
|
||||
// resize the file on upload if configured
|
||||
$file = $file->manipulate($create);
|
||||
|
||||
// store the content if necessary
|
||||
$file->save($file->content()->toArray(), $languageCode);
|
||||
// (always create files in the default language)
|
||||
$file->save(
|
||||
$file->content()->toArray(),
|
||||
$file->kirby()->defaultLanguage()?->code()
|
||||
);
|
||||
|
||||
// add the file to the list of siblings
|
||||
$file->siblings()->append($file->id(), $file);
|
||||
@@ -239,8 +282,6 @@ trait FileActions
|
||||
/**
|
||||
* Deletes the file. The store is used to
|
||||
* manipulate the filesystem or whatever you prefer.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(): bool
|
||||
{
|
||||
@@ -248,12 +289,8 @@ trait FileActions
|
||||
// remove all public versions, lock and clear UUID cache
|
||||
$file->unpublish();
|
||||
|
||||
if ($file->kirby()->multilang() === true) {
|
||||
foreach ($file->translations() as $translation) {
|
||||
F::remove($file->contentFile($translation->code()));
|
||||
}
|
||||
} else {
|
||||
F::remove($file->contentFile());
|
||||
foreach ($file->storage()->all() as $version => $lang) {
|
||||
$file->storage()->delete($version, $lang);
|
||||
}
|
||||
|
||||
F::remove($file->root());
|
||||
@@ -265,13 +302,29 @@ trait FileActions
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes/crops the original file with Kirby's thumb handler
|
||||
*/
|
||||
public function manipulate(array|null $options = []): static
|
||||
{
|
||||
// nothing to process
|
||||
if (empty($options) === true || $this->isResizable() === false) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
// generate image file and overwrite it in place
|
||||
$this->kirby()->thumb($this->root(), $this->root(), $options);
|
||||
|
||||
return $this->clone([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the file to the public media folder
|
||||
* if it's not already there.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function publish()
|
||||
public function publish(): static
|
||||
{
|
||||
Media::publish($this, $this->mediaRoot());
|
||||
return $this;
|
||||
@@ -284,12 +337,10 @@ trait FileActions
|
||||
* finally decides what it will support as
|
||||
* source.
|
||||
*
|
||||
* @param string $source
|
||||
* @param bool $move If set to `true`, the source will be deleted
|
||||
* @return static
|
||||
* @throws \Kirby\Exception\LogicException
|
||||
*/
|
||||
public function replace(string $source, bool $move = false)
|
||||
public function replace(string $source, bool $move = false): static
|
||||
{
|
||||
$file = $this->clone();
|
||||
|
||||
@@ -310,6 +361,11 @@ trait FileActions
|
||||
throw new LogicException('The file could not be created');
|
||||
}
|
||||
|
||||
// apply the resizing/crop options from the blueprint
|
||||
$create = $file->blueprint()->create();
|
||||
$file = $file->changeExtension($file, $create['format'] ?? null);
|
||||
$file = $file->manipulate($create);
|
||||
|
||||
// return a fresh clone
|
||||
return $file->clone();
|
||||
});
|
||||
@@ -317,15 +373,13 @@ trait FileActions
|
||||
|
||||
/**
|
||||
* Stores the content on disk
|
||||
*
|
||||
* @internal
|
||||
* @param array|null $data
|
||||
* @param string|null $languageCode
|
||||
* @param bool $overwrite
|
||||
* @return static
|
||||
*/
|
||||
public function save(array $data = null, string $languageCode = null, bool $overwrite = false)
|
||||
{
|
||||
public function save(
|
||||
array $data = null,
|
||||
string $languageCode = null,
|
||||
bool $overwrite = false
|
||||
): static {
|
||||
$file = parent::save($data, $languageCode, $overwrite);
|
||||
|
||||
// update model in siblings collection
|
||||
@@ -339,7 +393,7 @@ trait FileActions
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function unpublish(bool $onlyMedia = false)
|
||||
public function unpublish(bool $onlyMedia = false): static
|
||||
{
|
||||
// unpublish media files
|
||||
Media::unpublish($this->parent()->mediaRoot(), $this);
|
||||
@@ -354,4 +408,23 @@ trait FileActions
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the file's data and ensures that
|
||||
* media files get wiped if `focus` changed
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the input array contains invalid values
|
||||
*/
|
||||
public function update(
|
||||
array $input = null,
|
||||
string $languageCode = null,
|
||||
bool $validate = false
|
||||
): static {
|
||||
// delete all public media versions when focus field gets changed
|
||||
if (($input['focus'] ?? null) !== $this->focus()->value()) {
|
||||
$this->unpublish(true);
|
||||
}
|
||||
|
||||
return parent::update($input, $languageCode, $validate);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user