Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for old locks #6816

Merged
merged 8 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions panel/src/components/Views/PreviewView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,16 @@
</header>
<iframe v-if="hasChanges" ref="changes" :src="src.changes"></iframe>
<k-empty v-else>
{{ $t("lock.unsaved.empty") }}
<k-button icon="edit" variant="filled" :link="back">
{{ $t("edit") }}
</k-button>
<template v-if="lock.isLegacy">
This content is locked by our old lock system. <br />
Changes cannot be previewed.
</template>
<template v-else>
{{ $t("lock.unsaved.empty") }}
<k-button icon="edit" variant="filled" :link="back">
{{ $t("edit") }}
</k-button>
</template>
</k-empty>
</section>
</main>
Expand Down Expand Up @@ -223,6 +229,8 @@ export default {
flex-grow: 1;
justify-content: center;
flex-direction: column;
text-align: center;
padding-inline: var(--spacing-3);
gap: var(--spacing-6);
--button-color-text: var(--color-text);
}
Expand Down
16 changes: 16 additions & 0 deletions src/Api/Controller/Changes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace Kirby\Api\Controller;

use Kirby\Cms\ModelWithContent;
use Kirby\Content\Lock;
use Kirby\Content\VersionId;
use Kirby\Filesystem\F;
use Kirby\Form\Form;

/**
Expand All @@ -18,13 +20,23 @@
*/
class Changes
{
/**
* Cleans up legacy lock files
*/
protected static function cleanup(ModelWithContent $model): void
{
F::remove(Lock::legacyFile($model));
}

/**
* Discards unsaved changes by deleting the changes version
*/
public static function discard(ModelWithContent $model): array
{
$model->version(VersionId::changes())->delete('current');

static::cleanup($model);

return [
'status' => 'ok'
];
Expand All @@ -41,6 +53,8 @@ public static function publish(ModelWithContent $model, array $input): array
input: $input
);

static::cleanup($model);

// get the changes version
$changes = $model->version(VersionId::changes());

Expand Down Expand Up @@ -77,6 +91,8 @@ public static function save(ModelWithContent $model, array $input): array
$changes = $model->version(VersionId::changes());
$latest = $model->version(VersionId::latest());

static::cleanup($model);
bastianallgeier marked this conversation as resolved.
Show resolved Hide resolved

// combine the new field changes with the
// last published state
$changes->save(
Expand Down
62 changes: 61 additions & 1 deletion src/Content/Lock.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
use Kirby\Cms\App;
use Kirby\Cms\Language;
use Kirby\Cms\Languages;
use Kirby\Cms\ModelWithContent;
use Kirby\Cms\User;
use Kirby\Data\Data;
use Kirby\Toolkit\Str;

/**
Expand All @@ -27,6 +29,7 @@ class Lock
public function __construct(
protected User|null $user = null,
protected int|null $modified = null,
protected bool $legacy = false
) {
}

Expand All @@ -39,6 +42,11 @@ public static function for(
Version $version,
Language|string $language = 'default'
): static {

if ($legacy = static::legacy($version->model())) {
return $legacy;
}

// wildcard to search for a lock in any language
// the first locked one will be preferred
if ($language === '*') {
Expand Down Expand Up @@ -87,13 +95,21 @@ public function isActive(): bool
}

/**
* Check if content locking is enabled at all
* Checks if content locking is enabled at all
*/
public static function isEnabled(): bool
{
return App::instance()->option('content.locking', true) !== false;
}

/**
* Checks if the lock is coming from an old .lock file
*/
public function isLegacy(): bool
{
return $this->legacy;
}

/**
* Checks if the lock is actually locked
*/
Expand Down Expand Up @@ -124,6 +140,49 @@ public function isLocked(): bool
return true;
}

/**
* Looks for old .lock files and tries to create a
* usable lock instance from them
*/
public static function legacy(ModelWithContent $model): static|null
{
$kirby = $model->kirby();
$file = static::legacyFile($model);
$id = '/' . $model->id();

// no legacy lock file? no lock.
if (file_exists($file) === false) {
return null;
}

$data = Data::read($file, 'yml', fail: false)[$id] ?? [];

// no valid lock entry? no lock.
if (isset($data['lock']) === false) {
return null;
}

// has the lock been unlocked? no lock.
if (isset($data['unlock']) === true) {
return null;
}

return new static(
user: $kirby->user($data['lock']['user']),
modified: $data['lock']['time'],
legacy: true
);
}

/**
* Returns the absolute path to a legacy lock file
*/
public static function legacyFile(ModelWithContent $model): string
{
$root = $model::CLASS_ALIAS === 'file' ? dirname($model->root()) : $model->root();
bastianallgeier marked this conversation as resolved.
Show resolved Hide resolved
return $root . '/.lock';
}

/**
* Returns the timestamp when the locked content has
* been updated. You can pass a format to get a useful,
Expand All @@ -147,6 +206,7 @@ public function modified(
public function toArray(): array
{
return [
'isLegacy' => $this->isLegacy(),
'isLocked' => $this->isLocked(),
'modified' => $this->modified('c'),
'user' => [
Expand Down
1 change: 1 addition & 0 deletions tests/Content/LockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ public function testToArray()
);

$this->assertSame([
'isLegacy' => false,
'isLocked' => true,
'modified' => date('c', $modified),
'user' => [
Expand Down
3 changes: 3 additions & 0 deletions tests/Panel/Areas/SiteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function testPage(): void

$this->assertSame('default', $props['blueprint']);
$this->assertSame([
'isLegacy' => false,
'isLocked' => false,
'modified' => null,
'user' => [
Expand Down Expand Up @@ -95,6 +96,7 @@ public function testPageFile(): void

$this->assertSame('image', $props['blueprint']);
$this->assertSame([
'isLegacy' => false,
'isLocked' => false,
'modified' => null,
'user' => [
Expand Down Expand Up @@ -190,6 +192,7 @@ public function testSiteFile(): void

$this->assertSame('image', $props['blueprint']);
$this->assertSame([
'isLegacy' => false,
'isLocked' => false,
'modified' => null,
'user' => [
Expand Down