Jeroen De Dauw has uploaded a new change for review. https://gerrit.wikimedia.org/r/51695
Change subject: Clean up edit event creation and added basic test ...................................................................... Clean up edit event creation and added basic test Change-Id: I8e07da52c7fa8e2bfe95f400f3f695eaa49912b6 --- M EducationProgram.hooks.php M EducationProgram.php A includes/Events/EditEventCreator.php A tests/phpunit/Events/EditEventCreatorTest.php 4 files changed, 282 insertions(+), 64 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/EducationProgram refs/changes/95/51695/1 diff --git a/EducationProgram.hooks.php b/EducationProgram.hooks.php index 051beb4..a525571 100644 --- a/EducationProgram.hooks.php +++ b/EducationProgram.hooks.php @@ -71,6 +71,8 @@ 'Timeline', 'Utils', + 'Events/EditEventCreator', + 'rows/Article', 'tables/Orgs', @@ -426,78 +428,29 @@ * @return bool */ public static function onNewRevisionFromEditComplete( $article, Revision $rev, $baseID, User $user ) { - if ( !$user->isLoggedIn() ) { - return true; - } - wfProfileIn( __METHOD__ ); - $namespace = $article->getTitle()->getNamespace(); - if ( !in_array( $namespace, array( NS_MAIN, NS_TALK, NS_USER, NS_USER_TALK ) ) ) { - wfProfileOut( __METHOD__ ); - return true; + $eventCreator = new \EducationProgram\Events\EditEventCreator(); + $events = $eventCreator->getEventsForEdit( $article, $rev, $user ); + + $dbw = wfGetDB( DB_MASTER ); + + $startOwnStransaction = $dbw->trxLevel() === 0; + + if ( $startOwnStransaction ) { + $dbw->begin(); } - wfProfileIn( __METHOD__ . '-ns' ); - $conds = array( - 'upc_user_id' => $user->getId(), - 'upc_role' => EP_STUDENT, - ); + foreach ( $events as $event ) { + $event->save( __METHOD__ ); + } - $upc = wfGetDB( DB_SLAVE )->select( - array( 'ep_users_per_course', 'ep_courses' ), - array( 'upc_course_id' ), - array_merge( $conds, Courses::getStatusConds( 'current', true ) ), - __METHOD__, - array( 'DISTINCT' ), - array( - 'ep_courses' => array( 'INNER JOIN', array( 'upc_course_id=course_id' ) ), - ) - ); - - $hasCourses = $upc->numRows() !== 0; - wfProfileOut( __METHOD__ . '-ns' ); - - if ( $hasCourses ) { - wfProfileIn( __METHOD__ . '-courses' ); - if ( !is_null( $rev->getTitle() ) ) { - $event = Event::newFromRevision( $rev, $user ); - } - - $dbw = wfGetDB( DB_MASTER ); - - $startOwnStransaction = $dbw->trxLevel() === 0; - - if ( $startOwnStransaction ) { - $dbw->begin(); - } - - if ( !is_null( $rev->getTitle() ) ) { - while ( $link = $upc->fetchObject() ) { - $eventForCourse = clone $event; - $eventForCourse->setField( 'course_id', $link->upc_course_id ); - $eventForCourse->save(); - } - } - - if ( in_array( $namespace, array( NS_MAIN, NS_TALK ) ) ) { - $student = Student::newFromUserId( $user->getId(), true ); - - $student->setFields( array( - 'last_active' => wfTimestampNow() - ) ); - - $student->save(); - } - - if ( $startOwnStransaction ) { - $dbw->commit(); - } - - wfProfileIn( __METHOD__ . '-courses' ); + if ( $startOwnStransaction ) { + $dbw->commit(); } wfProfileOut( __METHOD__ ); + return true; } diff --git a/EducationProgram.php b/EducationProgram.php index be697a5..54afbe5 100644 --- a/EducationProgram.php +++ b/EducationProgram.php @@ -84,6 +84,8 @@ $wgAutoloadClasses['EducationProgram\ApiEnlist'] = $dir . '/includes/api/ApiEnlist.php'; $wgAutoloadClasses['EducationProgram\ApiRefreshEducation'] = $dir . '/includes/api/ApiRefreshEducation.php'; +$wgAutoloadClasses['EducationProgram\Events\EditEventCreator'] = $dir . '/includes/Events/EditEventCreator.php'; + // includes/pagers (implementing Pager) $wgAutoloadClasses['EducationProgram\ArticlePager'] = $dir . '/includes/pagers/ArticlePager.php'; $wgAutoloadClasses['EducationProgram\ArticleTable'] = $dir . '/includes/pagers/ArticleTable.php'; diff --git a/includes/Events/EditEventCreator.php b/includes/Events/EditEventCreator.php new file mode 100644 index 0000000..1e257a8 --- /dev/null +++ b/includes/Events/EditEventCreator.php @@ -0,0 +1,186 @@ +<?php + +namespace EducationProgram\Events; + +use EducationProgram\Event; +use EducationProgram\Courses; +use EducationProgram\Student; + +use Revision; +use User; +use Page; + +/** + * Class that generates edit based events by handling new edits. + * + * TODO: properly inject dependencies + * - DBConnectionProvider + * - Profiler + * - event factory + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.3 + * + * @file + * @ingroup EducationProgram + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class EditEventCreator { + + /** + * Takes the information of a newly created revision and uses this to + * create a list of education program events which is then returned. + * + * @since 0.3 + * + * @param Page $article + * @param Revision $rev + * @param User $user + * + * @return Event[] + */ + public function getEventsForEdit( Page $article, Revision $rev, User $user ) { + wfProfileIn( __METHOD__ ); + + if ( !$user->isLoggedIn() ) { + wfProfileOut( __METHOD__ ); + return array(); + } + + $namespace = $article->getTitle()->getNamespace(); + + if ( !in_array( $namespace, array( NS_MAIN, NS_TALK, NS_USER, NS_USER_TALK ) ) ) { + wfProfileOut( __METHOD__ ); + return array(); + } + + $courseIds = $this->getCoursesForUser( $user->getId() ); + + if ( empty( $courseIds ) ) { + $events = array(); + } + else { + $events = $this->createEditEvents( $rev, $user, $courseIds ); + + $this->updateLastActive( $namespace, $user ); + } + + wfProfileOut( __METHOD__ ); + + return $events; + } + + /** + * Returns the ids of the currently active courses the specified + * user is enrolled in. + * + * @since 0.3 + * + * @param int $userId + * + * @return int[] + */ + protected function getCoursesForUser( $userId ) { + wfProfileIn( __METHOD__ ); + + $conds = array( + 'upc_user_id' => $userId, + 'upc_role' => EP_STUDENT, + ); + + $upcRows = wfGetDB( DB_SLAVE )->select( + array( 'ep_users_per_course', 'ep_courses' ), + array( 'upc_course_id' ), + array_merge( $conds, Courses::getStatusConds( 'current', true ) ), + __METHOD__, + array( 'DISTINCT' ), + array( + 'ep_courses' => array( 'INNER JOIN', array( 'upc_course_id=course_id' ) ), + ) + ); + + $courseIds = array(); + + foreach ( $upcRows as $upcRow ) { + $courseIds[] = (int)$upcRow->upc_course_id; + } + + wfProfileOut( __METHOD__ ); + + return $courseIds; + } + + /** + * Creates the actual edit events. + * + * @since 0.3 + * + * @param Revision $rev + * @param User $user + * @param int[] $courseIds + * + * @return Event[] + */ + protected function createEditEvents( Revision $rev, User $user, array $courseIds ) { + wfProfileIn( __METHOD__ ); + + if ( is_null( $rev->getTitle() ) ) { + wfProfileOut( __METHOD__ ); + return array(); + } + + $event = Event::newFromRevision( $rev, $user ); + $events = array(); + + foreach ( $courseIds as $courseId ) { + $eventForCourse = clone $event; + $eventForCourse->setField( 'course_id', $courseId ); + $events[] = $eventForCourse; + } + + return $events; + } + + /** + * Updates the last activity of the student to be now. + * + * TODO: this should go into its own class + * + * @since 0.3 + * + * @param int $namespace + * @param User $user + */ + protected function updateLastActive( $namespace, User $user ) { + wfProfileIn( __METHOD__ ); + + if ( in_array( $namespace, array( NS_MAIN, NS_TALK ) ) ) { + $student = Student::newFromUserId( $user->getId(), true ); + + $student->setFields( array( + 'last_active' => wfTimestampNow() + ) ); + + $student->save(); + } + + wfProfileOut( __METHOD__ ); + } + +} diff --git a/tests/phpunit/Events/EditEventCreatorTest.php b/tests/phpunit/Events/EditEventCreatorTest.php new file mode 100644 index 0000000..5cf799f --- /dev/null +++ b/tests/phpunit/Events/EditEventCreatorTest.php @@ -0,0 +1,77 @@ +<?php + +namespace EducationProgram\Tests\Events; + +use EducationProgram\Events\EditEventCreator; +use EducationProgram\CoursePage; + +use Page; +use Revision; +use User; +use Title; +use WikiPage; + +/** + * Unit tests for the EducationProgram\Events\EditEventCreator class. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.3 + * + * @file + * @ingroup EducationProgramTest + * + * @group EducationProgram + * @group Database + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class EditEventCreatorTest extends \PHPUnit_Framework_TestCase { + + public function getEventsForEditProvider() { + $argLists = array(); + + $mainPage = new WikiPage( Title::newMainPage() ); + + $argLists[] = array( + $mainPage, + $mainPage->getRevision(), + new User() + ); + + $argLists[] = array( + new CoursePage( Title::newFromText( 'Foo/Bar', EP_NS ) ), + $mainPage->getRevision(), + new User() + ); + + return $argLists; + } + + /** + * @dataProvider getEventsForEditProvider + */ + public function testGetEventsForEdit( Page $article, Revision $rev, User $user ) { + $eventCreator = new EditEventCreator(); + + $events = $eventCreator->getEventsForEdit( $article, $rev, $user ); + + $this->assertInternalType( 'array', $events ); + $this->assertContainsOnlyInstancesOf( 'EducationProgram\Event', $events ); + } + +} -- To view, visit https://gerrit.wikimedia.org/r/51695 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8e07da52c7fa8e2bfe95f400f3f695eaa49912b6 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/EducationProgram Gerrit-Branch: master Gerrit-Owner: Jeroen De Dauw <jeroended...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits