Feature Wiki

Information about planned and released features

Tabs

IRSS: Draft-Revisions

1 Initial Problem

Files (resources) in the IRSS can already have versions - so-called revisions. These versions are created in the using components, for example, whenever users upload a new version.

These file versions are generally always "published" or directly available. We would like to introduce a new revision type "draft", which is available as such until it is made into a final/published revision by a person. The feature is available to all using components, how and whether it is used is up to the respective component.

In the file object, the feature would be used for the new possibility of editing files via WOPI. This means that changes via WOPI can be kept in draft form until they are explicitly published by a person with write access to the file object.

An explicit feature request is created for this purpose.

2 Conceptual Summary

The service is extended internally by revision types, through the use of interfaces this implementation is well possible. Draft revisions also have a version number (consecutive) like normal revisions. The stream of a draft version can be edited and changed as often as desired, the revision number remains. The IRSS ensures that no new (normal) revision can be created as long as a draft revision exists (which has the highest revision number).

User components can implement their own behaviour:

  • For example, blocking the possibility of uploading new versions as long as a draft exists.
  • ... or finalising a draft before a new version is created.

The IRSS does not specify any behaviour in this regard.

3 User Interface Modifications

3.1 List of Affected Views

  • None (Feature only in Backend)

3.2 User Interface Details

None

3.3 New User Interface Concepts

None

3.4 Accessibility Implications

None

4 Technical Information

A new ENUM RevisionStatus is introduced:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
 
/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

 
namespace ILIAS\ResourceStorage\Revision;
 
use ILIAS\ResourceStorage\Consumer\StreamAccess\Token;
 
/**
* @author Fabian Schmid <fabian@sr.solutions.ch>
*/

enum RevisionStatus: int
{
case PUBLISHED = 10;
case DRAFT = 20;
}

The following methods on the manager are extended so that new revisions could also be created as drafts:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @description Append a new revision from an UploadResult. By passing $draft = true, the revision will be created as a
* DRAFT on top of the current revision. Consumers will always use the latest published revision.
* Appending new Revisions is not possible if the latest revision is already a DRAFT. In this case,
* the DRAFT will be updated.
*/

public function appendNewRevision(
ResourceIdentification $identification,
UploadResult $result,
ResourceStakeholder $stakeholder,
string $revision_title = null,
bool $draft = false
): Revision {

Most of the time, however, you want to "edit" your own existing revision: The IRSS therefore converts the most recent "PUBLISHED" revision so that you receive a new revision as a draft. If the highest revision is already a draft revision, it will be delivered (Manager).

1
2
3
4
5
6
7
8
9
10
11
// Class \ILIAS\ResourceStorage\Manager\Manager
public function getCurrentRevision(
ResourceIdentification $identification
): Revision {
return $this->resource_builder->get($identification)->getCurrentRevision();
}
public function getCurrentRevisionIncludingDraft(
ResourceIdentification $identification
): Revision {
return $this->resource_builder->get($identification)->getCurrentRevisionIncludingDraft();
}

A component can "publish" a draft like this (Manager):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @description Publish a resource. A resource can contain a maximum of one revision in DRAFT on top status.
* This method can be used to publish this revision. If the latest revision is already published, nothing changes.
*/

public function publish(ResourceIdentification $rid): void
{
$this->resource_builder->publish($this->resource_builder->get($rid));
}
 
/**
* @description Unpublish a resource. The newest revision of a resource is set to the DRAFT status.
* If the latest revision is already in DRAFT, nothing changes.
*/

public function unpublish(ResourceIdentification $rid): void
{
$this->resource_builder->unpublish($this->resource_builder->get($rid));
}

5 Privacy

Revisions already have a reference to a user_id, see https://github.com/ILIAS-eLearning/ILIAS/blob/trunk/src/ResourceStorage/PRIVACY.md
This will not be changed or extended.

6 Security

From a safety perspective, there is no change to the previous implementation of the IRSS. Draft revisions are still revisions, but a status model is added.

7 Contact

8 Funding

If you are interest in funding this feature, please add your name and institution to this list.

9 Discussion

JourFixe, ILIAS [jourfixe], 10 JUL 2023 : We highly appreciate this suggestion and accept the feature for ILIAS 9.

10 Implementation

Please see the corresponsing PR for the public interface: https://github.com/ILIAS-eLearning/ILIAS/pull/6403

The Service can be used as described in the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Create new Resource from Upload
use ILIAS\ResourceStorage\Services;
global $DIC;
/** @var Services $irss */
$irss = $DIC['resource_storage'];
$upload_result = $DIC['upload']->getResults()['my_uploaded_file'];
$stakeholder = new ilMyComponentResourceStakeholder();
 
$rid = $irss->manage()->upload($upload_result, $stakeholder);
 
// later, add a draft:
$new_upload_result = $DIC['upload']->getResults()['my_uploaded_file'];
$revision = $irss->manage()->appendNewRevision($rid, $upload_result, $stakeholder, null, true);
 
// $revision->getStatus() is RevisionStatus::DRAFT
 
$latest_published_revision = $irss->manage()->getCurrentRevision($rid); // First upload
$latest_draft_revision = $irss->manage()->getCurrentRevisionIncludingDraft($rid); // Second Upload
 
$irss->manage()->publish($rid); // Publish the latest draft revision
$latest_published_revision = $irss->manage()->getCurrentRevision($rid); // Second File
$latest_published_revision = $irss->manage()->getCurrentRevisionIncludingDraft($rid); // Second File
 
// im some cases you want to unpublish the latest revision again
$irss->manage()->unpublish($rid);
$latest_published_revision = $irss->manage()->getCurrentRevision($rid); // First upload
$latest_draft_revision = $irss->manage()->getCurrentRevisionIncludingDraft($rid); // Second Upload

Test Cases

The draft revisions are used e.g. in the feature Implement WOPI for File-Editing and covered by test cases there.

Privacy

Information in privacy.md of component:  no change required

Approval

Approved at 2023-10-13 by Schmid, Fabian [fschmid].

Last edited: 16. Oct 2023, 14:22, Schmid, Fabian [fschmid]