Skip to content

Commit

Permalink
Add publish toggle to Hub, reflect status in CA (#3011)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmachughes authored Mar 7, 2025
1 parent 2fd4610 commit 3ee58d6
Show file tree
Hide file tree
Showing 69 changed files with 291 additions and 656 deletions.
6 changes: 5 additions & 1 deletion docs/docs/developers/content-types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,18 @@ support this, content selected via the default endpoint just replaces the previo

## Extended LTI parameters sent to LTI tools by the Hub

* `ext_edlib3_embed_resize_code`
* `ext_edlib3_embed_code`

The HTML code for letting the tool know how to embed the content. This will be an `<iframe>` element.

* `ext_edlib3_embed_resize_code`

The HTML code for including a script to resize the embedded content. This will be a `<script>` element.

* `ext_edlib3_published`

Sent by the hub when editing content. Will be `1` if published, or `0` otherwise.

## Resizing

Content can request that the Hub resize its iframe height. To do this, the content should send a message like so:
Expand Down
39 changes: 1 addition & 38 deletions sourcecode/apis/contentauthor/app/Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
* @property string|null $version_id
* @property int|null $max_score
* @property int $bulk_calculated
* @property bool $is_published
* @property string $license
* @property string $node_id
* @property Collection $collaborators
Expand Down Expand Up @@ -71,7 +70,6 @@ abstract class Content extends Model

protected $casts = [
'is_private' => 'boolean',
'is_published' => 'boolean',
'is_draft' => 'boolean',
];

Expand Down Expand Up @@ -325,20 +323,6 @@ private function getVersionedIds(ContentVersion $version): array
return $id;
}

/**
* The reason we have this function is that the isPublished function only returns the db value.
* We need a way to evaluate if a resource actually is published by using both the isPublished and isDraft flags
*/
public function isActuallyPublished(): bool
{
return $this->isPublished() && !$this->isDraft();
}

public function isPublished(): bool
{
return $this->is_published;
}

public function isListed(): bool
{
return !$this->is_private;
Expand All @@ -349,30 +333,9 @@ public function isDraft(): bool
return $this->is_draft;
}

public static function isUserPublishEnabled(): bool
{
/** @var H5PAdapterInterface $adapter */
$adapter = app(H5PAdapterInterface::class);
return $adapter->isUserPublishEnabled();
}

public function canList(Request $request): bool
{
if (!self::isUserPublishEnabled() || !$this->exists) {
return true;
}

$authId = $request->session()->get('authId') ?? false;
return $this->isOwner($authId) || $this->isCollaborator() || $this->isExternalCollaborator($authId);
}

public function canPublish(Request $request): bool
{
if (self::isUserPublishEnabled() || !$this->exists || ($request->importRequest ?? false)) {
return true;
}

return $this->canList($request) || $this->isCopyable();
return true;
}

/**
Expand Down
1 change: 0 additions & 1 deletion sourcecode/apis/contentauthor/app/H5PContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ class H5PContent extends Content implements VersionableObject

protected $casts = [
'library_id' => "int",
'is_published' => 'boolean',
'is_draft' => 'boolean',
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@ public function importH5P(H5PImportRequest $request, H5PImport $import, H5PStora
}

$h5pContent = H5PContent::find($response->h5pId);
if ($request->input('disablePublishMetadata', true) === true) {
config([
'feature.enableUserPublish' => false,
]);
}

event(new H5PWasSaved($h5pContent, $request, ContentVersion::PURPOSE_IMPORT));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Http\Controllers\API\Handler;

use App\Content;
use App\H5PContent;
use App\Http\Requests\H5PStorageRequest;
use App\Libraries\H5P\Helper\H5PPackageProvider;
Expand Down Expand Up @@ -35,7 +34,6 @@ public function storeQuestionset($questionsetData): H5PContent
'share' => $questionsetData['sharing'] === true || $questionsetData['sharing'] === "share" ? "share" : "private",
'license' => $questionsetData['license'],
'max_score' => array_key_exists('score', $questionsetData) ? $questionsetData['score'] : null,
'isPublished' => Content::isUserPublishEnabled() && array_key_exists('published', $questionsetData) ? $questionsetData['published'] : 1,
];

$request = new H5PStorageRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace App\Http\Controllers;

use App\Article;
use App\Content;
use App\ContentVersion;
use App\Events\ArticleWasSaved;
use App\Exceptions\UnhandledVersionReasonException;
Expand All @@ -14,7 +13,6 @@
use App\Libraries\DataObjects\LockedDataObject;
use App\Libraries\DataObjects\ResourceInfoDataObject;
use App\Libraries\H5P\Adapters\CerpusH5PAdapter;
use App\Libraries\H5P\Interfaces\H5PAdapterInterface;
use App\Libraries\HTMLPurify\Config\MathMLConfig;
use App\Lti\Lti;
use App\SessionKeys;
Expand Down Expand Up @@ -58,13 +56,8 @@ public function create(Request $request): View
],
]);

/** @var H5PAdapterInterface $adapter */
$adapter = app(H5PAdapterInterface::class);

$editorSetup = EditorConfigObject::create(
[
'userPublishEnabled' => $adapter->isUserPublishEnabled(),
'canPublish' => true,
'canList' => true,
'useLicense' => config('feature.licensing') === true || config('feature.licensing') === '1',
],
Expand Down Expand Up @@ -103,7 +96,6 @@ public function store(ArticleRequest $request): JsonResponse
// next line commented out in anticipation of permanently deciding if attribution for Articles is no longer maintained
//$article->updateAttribution($inputs['origin'] ?? null, $inputs['originators'] ?? []);

$article->is_published = $article::isUserPublishEnabled() ? $request->input('isPublished', 1) : 1;
$article->is_draft = $request->input('isDraft', 0);

$article->save();
Expand Down Expand Up @@ -153,6 +145,7 @@ public function show($id)
*/
public function edit(Request $request, $id)
{
$ltiRequest = $this->lti->getRequest($request);
$article = Article::findOrFail($id);

$origin = $article->getAttribution()->getOrigin();
Expand All @@ -170,8 +163,6 @@ public function edit(Request $request, $id)

$editorSetup = EditorConfigObject::create(
[
'userPublishEnabled' => Content::isUserPublishEnabled(),
'canPublish' => $article->canPublish($request),
'canList' => $article->canList($request),
'useLicense' => config('feature.licensing') === true || config('feature.licensing') === '1',
'pulseUrl' => config('feature.content-locking') ? route('lock.pulse', ['id' => $id]) : null,
Expand Down Expand Up @@ -206,7 +197,7 @@ public function edit(Request $request, $id)
'title' => $article->title,
'content' => $article->render(),
'license' => $article->license,
'isPublished' => $article->isPublished(),
'isPublished' => $ltiRequest?->getPublished() ?? false,
'isDraft' => $article->isDraft(),
'share' => !$article->isListed() ? 'private' : 'share',
'redirectToken' => $request->get('redirectToken'),
Expand Down Expand Up @@ -259,7 +250,6 @@ public function update(ArticleRequest $request, Article $article)
}
$article->max_score = $article->getMaxScoreHelper($article->content);
$article->license = $request->input('license', $oldLicense);
$article->is_published = $article::isUserPublishEnabled() ? $request->input('isPublished', 1) : 1;
$article->is_draft = $request->input('isDraft', false);

//$article->updateAttribution($request->input('origin'), $request->input('originators', []));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ public function create(Request $request, H5PCore $core, $contenttype = null): Vi
$ltiRequest = $this->lti->getRequest(request());

$editorSetup = H5PEditorConfigObject::create([
'userPublishEnabled' => $adapter->isUserPublishEnabled(),
'canPublish' => true,
'canList' => true,
'showDisplayOptions' => config('h5p.showDisplayOptions'),
'useLicense' => config('feature.licensing') === true || config('feature.licensing') === '1',
Expand Down Expand Up @@ -258,8 +256,6 @@ public function edit(Request $request, int $id): View
$ltiRequest = Session::get('lti_requests.' . $redirectToken);

$editorSetup = H5PEditorConfigObject::create([
'userPublishEnabled' => $adapter->isUserPublishEnabled(),
'canPublish' => $h5pContent->canPublish($request),
'canList' => $h5pContent->canList($request),
'showDisplayOptions' => config('h5p.showDisplayOptions'),
'useLicense' => config('feature.licensing') === true || config('feature.licensing') === '1',
Expand Down Expand Up @@ -314,7 +310,7 @@ public function edit(Request $request, int $id): View
'language_iso_639_3' => $contentLanguage,
'title' => $h5pContent->title,
'license' => $h5pContent->license ?: License::getDefaultLicense(),
'isPublished' => $h5pContent->isPublished(),
'isPublished' => $ltiRequest?->getPublished() ?? false,
'isDraft' => $h5pContent->isDraft(),
'share' => !$h5pContent->isListed() ? 'private' : 'share',
'redirectToken' => $request->get('redirectToken'),
Expand Down Expand Up @@ -384,9 +380,7 @@ public function update(H5PStorageRequest $request, H5PContent $h5p, H5PCore $cor
$responseValues = [
'url' => $this->getRedirectToCoreUrl(
$newH5pContent->toLtiContent(
published: H5PContent::isUserPublishEnabled()
? $request->validated('isPublished')
: null,
published: $request->validated('isPublished'),
shared: ($share = $request->validated('share'))
? $share === 'share'
: null,
Expand Down Expand Up @@ -450,9 +444,7 @@ public function store(H5PStorageRequest $request): Response|JsonResponse
$responseValues = [
'url' => $this->getRedirectToCoreUrl(
$content->toLtiContent(
published: H5PContent::isUserPublishEnabled()
? $request->validated('isPublished')
: null,
published: $request->validated('isPublished'),
shared: ($share = $request->validated('share'))
? $share === 'share'
: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
use App\Libraries\DataObjects\QuestionSetStateDataObject;
use App\Libraries\DataObjects\ResourceInfoDataObject;
use App\Libraries\Games\Millionaire\Millionaire;
use App\Libraries\H5P\Interfaces\H5PAdapterInterface;
use App\Libraries\QuestionSet\QuestionSetHandler;
use App\Lti\Lti;
use App\QuestionSet;
use App\SessionKeys;
use App\Traits\FractalTransformer;
Expand All @@ -30,7 +30,7 @@ class QuestionSetController extends Controller
use ReturnToCore;
use FractalTransformer;

public function __construct()
public function __construct(private readonly Lti $lti)
{
$this->middleware('lti.question-set')->only(['create']);
}
Expand All @@ -56,8 +56,6 @@ public function create(Request $request): View
Session::forget(SessionKeys::EXT_QUESTION_SET);

$editorSetup = EditorConfigObject::create([
'userPublishEnabled' => true,
'canPublish' => true,
'canList' => true,
'useLicense' => config('feature.licensing') === true || config('feature.licensing') === '1',
'editorLanguage' => Session::get('locale', config('app.fallback_locale')),
Expand Down Expand Up @@ -101,6 +99,7 @@ public function store(ApiQuestionsetRequest $request): JsonResponse

public function edit(Request $request, $id): View
{
$ltiRequest = $this->lti->getRequest($request);
$questionset = QuestionSet::findOrFail($id);

$links = (object) [
Expand All @@ -115,12 +114,7 @@ public function edit(Request $request, $id): View
$contenttypes = $this->getQuestionsetContentTypes();
$emails = $questionset->getCollaboratorEmails();

/** @var H5PAdapterInterface $adapter */
$adapter = app(H5PAdapterInterface::class);

$editorSetup = EditorConfigObject::create([
'userPublishEnabled' => $adapter->isUserPublishEnabled(),
'canPublish' => $questionset->canPublish($request),
'canList' => $questionset->canList($request),
'useLicense' => config('feature.licensing') === true || config('feature.licensing') === '1',
'editorLanguage' => Session::get('locale', config('app.fallback_locale')),
Expand All @@ -137,7 +131,7 @@ public function edit(Request $request, $id): View
'id' => $questionset->id,
'title' => $questionset->title,
'license' => $questionset->license,
'isPublished' => $questionset->isPublished(),
'isPublished' => $ltiRequest?->getPublished() ?? false,
'isDraft' => $questionset->isDraft(),
'share' => !$questionset->isListed() ? 'private' : 'share',
'redirectToken' => $request->get('redirectToken'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public function rules()
return [
'title' => 'required|string',
'sharing' => 'required|boolean',
'published' => 'sometimes|boolean',
'license' => 'required',
'authId' => 'required',
'questions' => 'required|array',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,16 @@

namespace App\Http\Requests;

use App\Content;
use App\Game;
use App\H5PContent;
use App\Libraries\Games\Millionaire\Millionaire;
use App\Libraries\H5P\Packages\QuestionSet;
use App\Rules\canPublishContent;
use App\Rules\LicenseContent;
use App\Rules\shareContent;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;
use App\QuestionSet as QuestionSetModel;

class ApiQuestionsetRequest extends FormRequest
{
private ?string $selectedPresentation;
private $contentModel;

/**
* Determine if the user is authorized to make this request.
Expand Down Expand Up @@ -53,7 +46,6 @@ public function rules()
'cards.*.answers.*.answerText' => 'required_with:cards.*.question.text|string',
'cards.*.answers.*.image' => 'present|array|nullable',
];
$this->contentModel = $this->route()->parameter('id') ?? new H5PContent();
break;
case Millionaire::$machineName:
$rules = [
Expand All @@ -66,7 +58,6 @@ public function rules()
'cards.*.answers.*.answerText' => 'required_with:cards.*.question.text|string',
'cards.*.answers.*.image' => 'present|array|nullable',
];
$this->contentModel = $this->route()->parameter('game') ?? new Game();
break;
default:
$rules = [
Expand All @@ -79,7 +70,6 @@ public function rules()
'cards.*.answers.*.answerText' => 'required_with:cards.*.question.text|string',
'cards.*.answers.*.image' => 'present|array|nullable',
];
$this->contentModel = $this->route()->parameter('questionset') ?? new QuestionSetModel();
}

return array_merge($this->getCommonRules(), $rules);
Expand Down Expand Up @@ -111,8 +101,7 @@ private function getCommonRules(): array
'questionSetJsonData' => 'sometimes|json',
'title' => 'required|string',
'tags' => 'present|array',
'isPublished' => [Rule::requiredIf(Content::isUserPublishEnabled()), 'boolean', new canPublishContent($this->contentModel, $this)],
'share' => ['sometimes', new shareContent(), new canPublishContent($this->contentModel, $this, 'list')],
'share' => ['sometimes', new shareContent()],
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace App\Http\Requests;

use App\Article;
use App\Rules\canPublishContent;
use App\Rules\LicenseContent;
use App\Rules\shareContent;
use Illuminate\Foundation\Http\FormRequest;
Expand All @@ -28,16 +26,14 @@ public function authorize()
*/
public function rules()
{
$article = $this->route()->parameter('article') ?? new Article();
return [
'title' => 'required|min:1|max:255',
'content' => 'required|filled',
'origin' => 'nullable|min:1,max:1000',
'originators' => 'nullable|array',
'originators.*.name' => 'required|min:1|max:1000',
'originators.*.role' => 'required|in:Source,Supplier,Writer',
'isPublished' => [Rule::requiredIf($article::isUserPublishEnabled()), 'boolean', new canPublishContent($article, $this)],
'share' => ['sometimes', new shareContent(), new canPublishContent($article, $this, 'list')],
'share' => ['sometimes', new shareContent()],
'license' => [Rule::requiredIf($this->input('share') === 'share'), 'string', app(LicenseContent::class)],
];
}
Expand Down
Loading

0 comments on commit 3ee58d6

Please sign in to comment.