AndyRussG has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/91613


Change subject: Let instructors and volunteers assign articles
......................................................................

Let instructors and volunteers assign articles

For instructors and volunteers, displays "Add an article" controls for
all students in their courses, on the course page. This allows said roles
to assign articles to students. See bug 56003. Also fixes issues in the
layout of the article table on course pages.

Bug: 56003
Change-Id: Ib9d036c4760b4ba847813e7cd4430bf4432109bc
---
M EducationProgram.php
M includes/actions/AddArticleAction.php
M includes/actions/ViewCourseAction.php
M includes/pagers/ArticleTable.php
A resources/ep.articletable.css
M resources/ep.articletable.js
6 files changed, 159 insertions(+), 53 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/EducationProgram 
refs/changes/13/91613/1

diff --git a/EducationProgram.php b/EducationProgram.php
index 2dc37c0..4bc8514 100644
--- a/EducationProgram.php
+++ b/EducationProgram.php
@@ -539,6 +539,9 @@
        'scripts' => array(
                'ep.articletable.js',
        ),
+       'styles' => array(
+               'ep.articletable.css'
+       ),
        'dependencies' => array(
                'jquery.ui.button',
                'jquery.ui.dialog',
diff --git a/includes/actions/AddArticleAction.php 
b/includes/actions/AddArticleAction.php
index c2b3c95..28a949a 100644
--- a/includes/actions/AddArticleAction.php
+++ b/includes/actions/AddArticleAction.php
@@ -30,8 +30,10 @@
        public function onView() {
                $req = $this->getRequest();
                $user = $this->getUser();
+               $courseId = $req->getInt( 'course-id' );
+               $studentUserId = $req->getInt( 'student-user-id' );
 
-               $salt = 'addarticle' . $req->getInt( 'course-id' );
+               $salt = 'addarticle' . $courseId . $studentUserId;
                $title = \Title::newFromText( $req->getText( 'addarticlename' ) 
);
 
                // TODO: some kind of warning when entering invalid title
@@ -40,13 +42,13 @@
                        // TODO: migrate into ArticleAdder
                        $course = Courses::singleton()->selectRow(
                                array( 'students', 'name' ),
-                               array( 'id' => $req->getInt( 'course-id' ) )
+                               array( 'id' => $courseId )
                        );
 
                        if ( $course !== false && in_array( $user->getId(), 
$course->getField( 'students' ) ) ) {
                                
Extension::globalInstance()->newArticleAdder()->addArticle(
-                                       $req->getInt( 'course-id' ),
-                                       $user->getId(),
+                                       $courseId,
+                                       $studentUserId,
                                        $title->getArticleID(),
                                        $title->getFullText()
                                );
diff --git a/includes/actions/ViewCourseAction.php 
b/includes/actions/ViewCourseAction.php
index 7f67a94..3c877ac 100644
--- a/includes/actions/ViewCourseAction.php
+++ b/includes/actions/ViewCourseAction.php
@@ -127,7 +127,9 @@
                        $pager = new ArticleTable(
                                $this->getContext(),
                                array( 'user_id' => $studentIds ),
-                               $course->getId()
+                               $course->getId(),
+                               null,
+                               $course
                        );
 
                        $pager->mLimit = 200;
diff --git a/includes/pagers/ArticleTable.php b/includes/pagers/ArticleTable.php
index eac1cf0..7b3f83a 100644
--- a/includes/pagers/ArticleTable.php
+++ b/includes/pagers/ArticleTable.php
@@ -40,6 +40,15 @@
        protected $courseIds;
 
        /**
+        * The course object for these articles, if the table is for only one 
course.
+        *
+        * TODO check version
+        * @since 0.4alpa??
+        * @var Course
+        */
+       protected $course;
+
+       /**
         * Id of the user all articles should belong to
         * or null for no such restriction.
         *
@@ -71,11 +80,15 @@
         * @param array $conds
         * @param int[]|int $courseIds
         * @param int[]|null $userIds
+        * @param Course $course The course object or these articles. Should be 
sent
+        *   when the table is for only one course.
         */
-       public function __construct( IContextSource $context, array $conds = 
array(), $courseIds, array $userIds = null ) {
+       public function __construct( IContextSource $context, array $conds = 
array(),
+                       $courseIds, array $userIds = null, $course = null ) {
                $this->mDefaultDirection = true;
                $this->courseIds = (array)$courseIds;
                $this->userIds = $userIds;
+               $this->course = $course;
 
                parent::__construct( $context, $conds, Students::singleton() );
        }
@@ -145,34 +158,82 @@
                $student = $this->currentObject;
                $articles = $this->articles[$student->getField( 'user_id' )];
                $user = $this->getUser();
+               $userId = $user->getId();
+               $showArticleAddition = false;
 
+               // Show the article addition control for this student?
+               // Only if the table contains articles for only one course, 
and...
+               if ( $this->isForOneCourse() ) {
+
+                       // ...the user is the student referred to by this row, 
or...
+                       if ( $user->getId() === $student->getField( 'user_id' ) 
) {
+
+                               $showArticleAddition = true;
+
+                       // we received a valid $this->course object, and the 
user is
+                       // an instructor, an online ambassador or a campus 
ambassador
+                       // for this course.
+                       } elseif ( !is_null($this->course) &&
+                               ( $this->isInRoleList( $userId, 
$this->course->getInstructors() ) ||
+                               $this->isInRoleList( $userId, 
$this->course->getOnlineAmbassadors() ) ||
+                               $this->isInRoleList( $userId, 
$this->course->getCampusAmbassadors() ) ) ) {
+
+                               $showArticleAddition = true;
+                       }
+               }
+
+               // initial calculation for row count
                $rowCount = array_reduce(
                        $articles,
                        function( /* integer */ $sum, EPArticle $article ) use 
( $user ) {
-                               if ( $article->canBecomeReviewer( $user ) ) {
-                                       $sum++;
+
+                               // At least one row per article the student has 
to review;
+                               // for articles that have more than one 
reviewer, provide extra rows for them.
+                               $reviewersCount = count( 
$article->getReviewers() );
+                               $inc = max( 1, $reviewersCount );
+
+                               // The "Become a reviewer" control also adds an 
extra row, unless there are no
+                               // reviewers.
+                               if ( $article->canBecomeReviewer( $user ) && ( 
$reviewersCount > 0 ) ) {
+                                       $inc++;
                                }
 
-                               return $sum + count( $article->getReviewers() );
+                               return $sum + $inc;
                        },
                        0
                );
 
-               $html = Html::openElement( 'tr', $this->getRowAttrs( $row ) );
-
-               $showArticleAddition =
-                       $user->getId() === $student->getField( 'user_id' )
-                       && $this->isForOneCourse();
-
-               if ( $this->showStudents ) {
-                       $html .= $this->getUserCell( $student->getField( 
'user_id' ), max( 1, $rowCount ) );
+               // one extra row for showing the article addition control 
(which spans the
+               // last two columns)
+               if ($showArticleAddition) {
+                       $rowCount++;
                }
 
-               $this->addNonStudentHTML( $html, $articles, 
$showArticleAddition );
+               // must be at least one, even if there's nothing in the 
following columns
+               $rowCount = max( 1, $rowCount );
+
+               $html = Html::openElement( 'tr', $this->getRowAttrs( $row ) );
+
+               $studentUserId = $student->getField( 'user_id' );
+
+               if ( $this->showStudents ) {
+                       $html .= $this->getUserCell( $studentUserId, $rowCount 
);
+               }
+
+               $this->addNonStudentHTML( $html, $articles, 
$showArticleAddition, $studentUserId );
 
                $html .= '</tr>';
 
                return $html;
+       }
+
+       private function isInRoleList($userId, $roleList) {
+               return in_array(
+                       $userId,
+                       array_map(
+                               function( $u ) { return $u->getUser()->getId(); 
},
+                               $roleList )
+                       );
        }
 
        /**
@@ -184,7 +245,7 @@
         * @param array $articles
         * @param boolean $showArticleAddition
         */
-       protected function addNonStudentHTML( &$html, array $articles, 
$showArticleAddition ) {
+       protected function addNonStudentHTML( &$html, array $articles, 
$showArticleAddition, $studentUserId ) {
                $isFirst = true;
 
                /**
@@ -199,9 +260,11 @@
 
                        $reviewers = $article->getReviewers();
 
+                       $canBecomeReviewer = $article->canBecomeReviewer( 
$this->getUser() );
+
                        $articleRowCount = count( $reviewers );
 
-                       if ( $article->canBecomeReviewer( $this->getUser() ) ) {
+                       if ($canBecomeReviewer) {
                                $articleRowCount++;
                        }
 
@@ -209,15 +272,19 @@
 
                        $html .= $this->getArticleCell( $article, 
$articleRowCount );
 
+                       $isFirstReviewer = true;
+
                        foreach ( $reviewers as $nr => $userId ) {
-                               if ( $nr !== 0 ) {
+                               if ( !$isFirstReviewer ) {
                                        $html .= '</tr><tr>';
                                }
+
+                               $isFirstReviewer = false;
 
                                $html .= $this->getReviewerCell( $article, 
$userId );
                        }
 
-                       if ( $article->canBecomeReviewer( $this->getUser() ) ) {
+                       if ( $canBecomeReviewer ) {
                                if ( count( $reviewers ) !== 0 ) {
                                        $html .= '</tr><tr>';
                                }
@@ -234,7 +301,7 @@
                                $html .= '</tr><tr>';
                        }
 
-                       $html .= $this->getArticleAdditionControl( reset( 
$this->courseIds ) );
+                       $html .= $this->getArticleAdditionControl( reset( 
$this->courseIds ), $studentUserId );
                }
                elseif ( $isFirst ) {
                        $html .= '<td></td><td></td>';
@@ -477,7 +544,7 @@
         *
         * @return string
         */
-       protected function getArticleAdditionControl( $courseId ) {
+       protected function getArticleAdditionControl( $courseId, $studentUserId 
) {
                $courseTitle = Courses::singleton()->selectFieldsRow( 'title', 
array( 'id' => $courseId ) );
                $query = array( 'action' => 'epaddarticle' );
 
@@ -496,7 +563,10 @@
                $html .=  Xml::inputLabel(
                        $this->msg( 'ep-articles-addarticle-text' )->text(),
                        'addarticlename',
-                       'addarticlename'
+                       'addarticlename',
+                       false,
+                       false,
+                       array ( 'class' => 'ep-addarticlename' )
                );
 
                $html .= '&#160;' . Html::input(
@@ -509,11 +579,12 @@
                );
 
                $html .= Html::hidden( 'course-id', $courseId );
-               $html .= Html::hidden( 'token', $this->getUser()->getEditToken( 
'addarticle' . $courseId ) );
+               $html .= Html::hidden( 'token', $this->getUser()->getEditToken( 
'addarticle' . $courseId . $studentUserId) );
+               $html .= Html::hidden( 'student-user-id', $studentUserId );
 
                $html .= '</form>';
 
-               return '<td colspan="2">' . $html . '</td>';
+               return '<td colspan="2" class="ep-addarticle-cell">' . $html . 
'</td>';
        }
 
        /**
diff --git a/resources/ep.articletable.css b/resources/ep.articletable.css
new file mode 100644
index 0000000..16501f6
--- /dev/null
+++ b/resources/ep.articletable.css
@@ -0,0 +1,22 @@
+/**
+ * CSS for the Education Program MediaWiki extension.
+ * @see https://www.mediawiki.org/wiki/Extension:Education_Program
+ *
+ * @licence GNU GPL v2+
+ * @author Andrew Green <andrew.green.df at gmail dot com>
+ */
+
+.ep-articletable td,
+.ep-articletable th {
+       padding: 4px;
+}
+
+.ep-articletable-row,
+.ep-articletable th {
+       border-top: 2px solid rgb(150, 150, 150);
+}
+
+.ep-addarticle-cell {
+       background-color: #f2f2f2 !important;
+}
+
diff --git a/resources/ep.articletable.js b/resources/ep.articletable.js
index 0365bc4..e6a47f0 100644
--- a/resources/ep.articletable.js
+++ b/resources/ep.articletable.js
@@ -263,6 +263,34 @@
                return false;
        }
 
+       function autocompleteSource( request, response ) {
+               $.getJSON(
+                       mw.config.get( 'wgScriptPath' ) + '/api.php',
+                       {
+                               'action': 'opensearch',
+                               'format': 'json',
+                               'search': request.term,
+                               'limit': 8
+                       },
+                       function( data ) {
+                               response( $.map( data[1], function( item ) {
+                                       return {
+                                               'label': item,
+                                               'value': item
+                                       };
+                               } ) );
+                       }
+               );
+       }
+
+       function autocompleteOpen() {
+               $( this ).removeClass( "ui-corner-all" ).addClass( 
"ui-corner-top" );
+       }
+
+       function autocompleteClose() {
+               $( this ).removeClass( "ui-corner-top" ).addClass( 
"ui-corner-all" );
+       }
+
        $( document ).ready( function() {
 
                $( '.ep-rem-reviewer-self, .ep-become-reviewer' ).removeAttr( 
'disabled' );
@@ -275,33 +303,11 @@
 
                $( '.ep-rem-article' ).click( removeArticle );
 
-               $( '#addarticlename' ).autocomplete( {
-                       source: function( request, response ) {
-                               $.getJSON(
-                                       mw.config.get( 'wgScriptPath' ) + 
'/api.php',
-                                       {
-                                               'action': 'opensearch',
-                                               'format': 'json',
-                                               'search': request.term,
-                                               'limit': 8
-                                       },
-                                       function( data ) {
-                                               response( $.map( data[1], 
function( item ) {
-                                                       return {
-                                                               'label': item,
-                                                               'value': item
-                                                       };
-                                               } ) );
-                                       }
-                               );
-                       },
+               $( '.ep-addarticlename' ).autocomplete( {
+                       source: autocompleteSource,
                        minLength: 2,
-                       open: function() {
-                               $( this ).removeClass( "ui-corner-all" 
).addClass( "ui-corner-top" );
-                       },
-                       close: function() {
-                               $( this ).removeClass( "ui-corner-top" 
).addClass( "ui-corner-all" );
-                       }
+                       open: autocompleteOpen,
+                       close: autocompleteClose
                } );
 
        } );

-- 
To view, visit https://gerrit.wikimedia.org/r/91613
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib9d036c4760b4ba847813e7cd4430bf4432109bc
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/EducationProgram
Gerrit-Branch: master
Gerrit-Owner: AndyRussG <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to