Sebschlicht2 has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/341002 )
Change subject: Hook to simplify MOOC creation ...................................................................... Hook to simplify MOOC creation In order to simplify the process of adding a MOOC, this change adds a hook for page creation within the MOOC namespace. Whenever a root MOOC page is created, a MoocOverview stub is injected into the edit box. Together with this change, the MoocEntity class tree has slighlty be changed to allow a convenient usage of these classes inside the hook. Additionally, the structure loading query has been fixed together with the stub of lessons in the edit-JS. Change-Id: I28538a52af765d0fe88dfba2dc2a565ffbd873f6 --- M MOOC.hooks.php M extension.json M includes/content/MoocContent.php M includes/model/MoocEntity.php M includes/model/MoocItem.php M includes/model/MoocLesson.php M includes/model/MoocOverview.php M includes/model/MoocResource.php M includes/structure/MoocContentStructureProvider.php M resources/js/ext.mooc.edit.js 10 files changed, 118 insertions(+), 60 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MOOC refs/changes/02/341002/1 diff --git a/MOOC.hooks.php b/MOOC.hooks.php index 8aa1e00..101f54d 100644 --- a/MOOC.hooks.php +++ b/MOOC.hooks.php @@ -12,6 +12,20 @@ class MOOCHooks { /** + * Fills the edit form of a MOOC page with the MOOC overview JSON to allow fluent creates of MOOCs. + * + * @param string $text text to pre-fill the edit form with + * @param Title $title title of the new page + */ + public static function onEditFormPreloadText( &$text, &$title ) { + if ( $title->getContentModel() === MoocContent::CONTENT_MODEL_MOOC_ITEM ) { + if ( $title->equals( $title->getRootTitle() ) ) { + $text = json_encode( ( new MoocOverview() )->toJson() ); + } + } + } + + /** * Transforms a MOOC resource into Wikitext to allow users to edit its content. * * @param EditPage $editPage edit page diff --git a/extension.json b/extension.json index a972c68..b6131df 100644 --- a/extension.json +++ b/extension.json @@ -44,6 +44,9 @@ "EditFormInitialText": [ "MOOCHooks::onEditFormInitialText" ], + "EditFormPreloadText": [ + "MOOCHooks::onEditFormPreloadText" + ], "EditPageGetPreviewContent": [ "MOOCHooks::onEditPageGetPreviewContent" ], diff --git a/includes/content/MoocContent.php b/includes/content/MoocContent.php index 3fd7510..24fe9fd 100644 --- a/includes/content/MoocContent.php +++ b/includes/content/MoocContent.php @@ -34,7 +34,7 @@ * @return MoocEntity MOOC entity loaded from the content */ public function loadItem() { - return MoocEntity::loadFromJson( null, (array) parent::getData()->getValue() ); + return MoocEntity::fromJson( (array) parent::getData()->getValue() ); } /** @@ -82,6 +82,10 @@ $output->setEnableOOUI( true ); $output->addModuleScripts( 'ext.mooc' ); $output->addModuleStyles( 'ext.mooc' ); + + // add Bootstrap + $bootstrapManager = \Bootstrap\BootstrapManager::getInstance(); + $bootstrapManager->addAllBootstrapModules(); $output->addModuleStyles( 'ext.bootstrap.styles' ); $output->setText( MoocContentRenderer::renderItem( $output, $this->entity ) ); diff --git a/includes/model/MoocEntity.php b/includes/model/MoocEntity.php index fc030bc..4a56099 100644 --- a/includes/model/MoocEntity.php +++ b/includes/model/MoocEntity.php @@ -26,52 +26,77 @@ public $type; /** - * Creates a new MOOC entity from JSON. + * Creates an empty MOOC entity. * + * @param string $type entity type identifier * @param Title $title page title - * @param array $moocContentJson JSON (associative array) representing a MOOC entity */ - public function __construct( $title, $moocContentJson ) { + public function __construct( $type, $title = null ) { + $this->type = $type; // TODO completely separate page Title from MOOC entities? $this->title = $title; - $this->type = $moocContentJson[self::JFIELD_TYPE]; } + + /** + * Loads the entity fields from a JSON array. + * + * @param array $jsonArray associative array (e.g. from json_decode) + */ + abstract protected function loadJson( $jsonArray ); /** * Converts this MOOC entity into JSON content. * * @return array JSON (associative array) representing a MOOC entity */ - abstract function toJson(); + abstract public function toJson(); /** - * Loads a MOOC entity from JSON content. + * Loads a MOOC entity from a JSON array. * - * @param Title $title title of the MOOC entity page - * @param array $moocContentJson JSON (associative array) representing a MOOC entity - * @return MoocEntity MOOC entity instance or null on error + * @param array $jsonArray associative array (e.g. from json_decode) + * @param Title $title page title + * @return MoocLesson|MoocOverview|MoocQuiz|MoocScript|MoocUnit|null MOOC entity or <i>null</i> if the entity type + * was not specified or is unknown */ - public static function loadFromJson( $title, $moocContentJson ) { - if ( !array_key_exists( self::JFIELD_TYPE, $moocContentJson ) ) { + public static function fromJson( $jsonArray, $title = null ) { + // extract entity type + if ( !array_key_exists( self::JFIELD_TYPE, $jsonArray ) ) { return null; } + $type = $jsonArray[self::JFIELD_TYPE]; - $type = $moocContentJson[self::JFIELD_TYPE]; + // instantiate entity by type and load values from JSON array + $entity = self::instantiate( $type, $title ); + if ( $entity !== null ) { + $entity->loadJson( $jsonArray ); + } + return $entity; + } + + /** + * Instantiates a MOOC entity by its type. + * + * @param string $type MOOC entity type identifier + * @param Title $title page title + * @return MoocLesson|MoocOverview|MoocQuiz|MoocScript|MoocUnit|null MOOC entity or <i>null</i> if type is unknown + */ + protected static function instantiate ( $type, $title = null ) { switch ( $type ) { case MoocUnit::ENTITY_TYPE_UNIT: - return new MoocUnit( $title, $moocContentJson ); + return new MoocUnit( $type, $title ); case MoocLesson::ENTITY_TYPE_LESSON: - return new MoocLesson( $title, $moocContentJson ); + return new MoocLesson( $type, $title ); case MoocOverview::ENTITY_TYPE_MOOC: - return new MoocOverview( $title, $moocContentJson ); + return new MoocOverview( $type, $title ); case MoocScript::ENTITY_TYPE_SCRIPT: - return new MoocScript( $title, $moocContentJson ); + return new MoocScript( $type, $title ); case MoocQuiz::ENTITY_TYPE_QUIZ: - return new MoocQuiz( $title, $moocContentJson ); + return new MoocQuiz( $type, $title ); // unknown MOOC entity type default: diff --git a/includes/model/MoocItem.php b/includes/model/MoocItem.php index 3f5861e..abaeb62 100644 --- a/includes/model/MoocItem.php +++ b/includes/model/MoocItem.php @@ -73,38 +73,34 @@ */ public $children; - /** - * Creates a new MOOC item from JSON. - * - * @param Title $title page title - * @param array $moocContentJson JSON (associative array) representing a MOOC item - */ - public function __construct( $title, $moocContentJson ) { - // TODO completely separate Title from MoocItem? - parent::__construct( $title, $moocContentJson ); - $this->setTitle( $title ); + public function __construct( $type, $title = null ) { + parent::__construct( $type, $title ); - // common MOOC item fields - if ( array_key_exists( self::JFIELD_VIDEO, $moocContentJson ) ) { - $this->video = $moocContentJson[self::JFIELD_VIDEO]; + // set script and quiz title + $this->setTitle( $title ); + } + + protected function loadJson( $jsonArray ) { + if ( array_key_exists( self::JFIELD_VIDEO, $jsonArray ) ) { + $this->video = $jsonArray[self::JFIELD_VIDEO]; } - if ( array_key_exists( self::JFIELD_LEARNING_GOALS, $moocContentJson ) ) { - $this->learningGoals = $moocContentJson[self::JFIELD_LEARNING_GOALS]; + if ( array_key_exists( self::JFIELD_LEARNING_GOALS, $jsonArray ) ) { + $this->learningGoals = $jsonArray[self::JFIELD_LEARNING_GOALS]; } - if ( array_key_exists( self::JFIELD_FURTHER_READING, $moocContentJson ) ) { - $this->furtherReading = $moocContentJson[self::JFIELD_FURTHER_READING]; + if ( array_key_exists( self::JFIELD_FURTHER_READING, $jsonArray ) ) { + $this->furtherReading = $jsonArray[self::JFIELD_FURTHER_READING]; } } /** + * Sets the title and updates the titles of potentially associated resources. + * * @param $title Title page title */ public function setTitle( $title ) { $this->title = $title; - if ( $title != null ) { - $this->scriptTitle = Title::newFromText( $title . '/script' ); - $this->quizTitle = Title::newFromText( $title . '/quiz' ); - } + $this->scriptTitle = ( $title === null ) ? null : Title::newFromText( $title . '/script' ); + $this->quizTitle = ( $title === null ) ? null : Title::newFromText( $title . '/quiz' ); } /** @@ -126,8 +122,6 @@ self::JFIELD_TYPE => $this->type, self::JFIELD_LEARNING_GOALS => $this->learningGoals, self::JFIELD_VIDEO => $this->video, - self::JFIELD_SCRIPT_TITLE => $this->scriptTitle->getFullText(), - self::JFIELD_QUIZ_TITLE => $this->quizTitle->getFullText(), self::JFIELD_FURTHER_READING => $this->furtherReading ]; } diff --git a/includes/model/MoocLesson.php b/includes/model/MoocLesson.php index e3ede7b..21bc55b 100644 --- a/includes/model/MoocLesson.php +++ b/includes/model/MoocLesson.php @@ -14,16 +14,16 @@ */ const ENTITY_TYPE_LESSON = 'lesson'; - /** - * @param Title $title page title - * @param mixed $moocContentJson JSON (associative array) representing a MOOC lesson - */ - public function __construct($title, $moocContentJson) { - parent::__construct($title, $moocContentJson); + public function __construct( $title = null ) { + parent::__construct( self::ENTITY_TYPE_LESSON, $title ); + } + + protected function loadJson($jsonArray) { + parent::loadJson( $jsonArray ); // child units - if (array_key_exists(self::JFIELD_CHILDREN, $moocContentJson)) { - $this->childNames = $moocContentJson[self::JFIELD_CHILDREN]; + if ( array_key_exists( self::JFIELD_CHILDREN, $jsonArray ) ) { + $this->childNames = $jsonArray[self::JFIELD_CHILDREN]; } } } diff --git a/includes/model/MoocOverview.php b/includes/model/MoocOverview.php index ca2f133..ea504e1 100644 --- a/includes/model/MoocOverview.php +++ b/includes/model/MoocOverview.php @@ -14,6 +14,10 @@ */ const ENTITY_TYPE_MOOC = 'mooc'; + public function __construct( $title = null ) { + parent::__construct( self::ENTITY_TYPE_MOOC, $title ); + } + public function toJson() { return [ self::JFIELD_TYPE => $this->type, diff --git a/includes/model/MoocResource.php b/includes/model/MoocResource.php index bbb1f2e..444813d 100644 --- a/includes/model/MoocResource.php +++ b/includes/model/MoocResource.php @@ -21,16 +21,10 @@ */ public $content; - /** - * @param Title $title resource page title - * @param mixed $moocContentJson JSON (associative array) representing a MOOC resource - */ - public function __construct( $title, $moocContentJson ) { - parent::__construct( $title, $moocContentJson ); - + protected function loadJson( $jsonArray ) { // resource file content - if any - if ( array_key_exists( self::JFIELD_CONTENT, $moocContentJson ) ) { - $this->content = $moocContentJson[self::JFIELD_CONTENT]; + if ( array_key_exists( self::JFIELD_CONTENT, $jsonArray ) ) { + $this->content = $jsonArray[self::JFIELD_CONTENT]; } } diff --git a/includes/structure/MoocContentStructureProvider.php b/includes/structure/MoocContentStructureProvider.php index d1cefd6..2cd872b 100644 --- a/includes/structure/MoocContentStructureProvider.php +++ b/includes/structure/MoocContentStructureProvider.php @@ -31,7 +31,8 @@ ), array( 'page_title', 'old_text' - ), "page_title LIKE '$rootPageTitle%' AND page_namespace = '$namespace' AND page_content_model = '$contentModelId'", + ), "(page_title = '$rootPageTitle' OR page_title LIKE '$rootPageTitle/%')" + . " AND page_namespace = '$namespace' AND page_content_model = '$contentModelId'", __METHOD__, array( 'ORDER_BY' => 'page_title ASC' ), array( @@ -64,6 +65,22 @@ // load structure from item titles //TODO this requires the items to be sorted by title while children arrays MUST maintain the original creation ordering $rootItem = array_shift( $items ); + if ( $rootItem === null ) { + // the MOOC is not existing yet -> simulate MOOC overview and parental lesson, if necessary + if ( $renderedItem instanceof MoocOverview ) { + $rootItem = $renderedItem; + } else { + $rootItem = new MoocOverview( $renderedItem->title->getRootTitle() ); + + // create parental lesson if unit + if ( $renderedItem instanceof MoocUnit ) { + $lesson = new MoocLesson( $renderedItem->title->getBaseTitle() ); + array_push( $items, $lesson ); + } + array_push( $items, $renderedItem ); + } + } + $prevLesson = null; foreach ( $items as $item ) { // determine item parent diff --git a/resources/js/ext.mooc.edit.js b/resources/js/ext.mooc.edit.js index 0ff6fc6..5548f24 100644 --- a/resources/js/ext.mooc.edit.js +++ b/resources/js/ext.mooc.edit.js @@ -193,6 +193,9 @@ * @returns {*} jQuery-promise on the AJAX request */ function apiSaveItem( title, item, summary ) { + // remove temporary values TODO is there a better way to do this? prevents to extend the JSON by these fields + delete item.script; + delete item.quiz; return apiSavePage( title, JSON.stringify( item ), summary ); } @@ -220,7 +223,7 @@ */ function apiAddLessonToMooc( moocTitle, lessonName ) { var lessonTitle = moocTitle + '/' + lessonName; - var content = '{"type":"mooc"}'; + var content = '{"type":"lesson"}'; var summary = mw.message( 'mooc-overview-add-lesson-summary', lessonName ).text(); mw.log( 'adding lesson ' + lessonName + ' (' + lessonTitle + ') to MOOC ' + moocTitle ); -- To view, visit https://gerrit.wikimedia.org/r/341002 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I28538a52af765d0fe88dfba2dc2a565ffbd873f6 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/MOOC Gerrit-Branch: master Gerrit-Owner: Sebschlicht2 <sebschli...@uni-koblenz.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits