Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php |
— | — | @@ -489,7 +489,7 @@ |
490 | 490 | # Determine what pages can be moved and patrolled |
491 | 491 | $wgHooks['getUserPermissionsErrors'][] = 'FlaggedRevsHooks::onUserCan'; |
492 | 492 | # Implicit autoreview rights group |
493 | | -$wgHooks['GetAutoPromoteGroups'][] = 'FlaggedRevsHooks::checkAutoPromote'; |
| 493 | +$wgHooks['AutopromoteCondition'][] = 'FlaggedRevsHooks::checkAutoPromoteCond'; |
494 | 494 | |
495 | 495 | # Check if a page is currently being reviewed |
496 | 496 | $wgHooks['MediaWikiPerformAction'][] = 'FlaggedRevsUIHooks::onMediaWikiPerformAction'; |
— | — | @@ -559,6 +559,28 @@ |
560 | 560 | $wgUseRCPatrol = true; |
561 | 561 | } |
562 | 562 | } |
| 563 | + global $wgFlaggedRevsAutoconfirm, $wgAutopromote; |
| 564 | + # $wgFlaggedRevsAutoconfirm is now a wrapper around $wgAutopromote |
| 565 | + if ( is_array( $wgFlaggedRevsAutoconfirm ) ) { |
| 566 | + $wgAutopromote['autoreview'] = array( '&', // AND |
| 567 | + array( APCOND_AGE, $wgFlaggedRevsAutoconfirm['days']*86400 ), |
| 568 | + array( APCOND_EDITCOUNT, $wgFlaggedRevsAutoconfirm['edits'] ), |
| 569 | + array( APCOND_FR_EDITSUMMARYCOUNT, $wgFlaggedRevsAutoconfirm['editComments'] ), |
| 570 | + array( APCOND_FR_UNIQUEPAGECOUNT, $wgFlaggedRevsAutoconfirm['uniqueContentPages'] ), |
| 571 | + array( APCOND_FR_EDITSPACING, |
| 572 | + $wgFlaggedRevsAutoconfirm['spacing'], $wgFlaggedRevsAutoconfirm['benchmarks'] ), |
| 573 | + array( '|', // OR |
| 574 | + array( APCOND_FR_CONTENTEDITCOUNT, $wgFlaggedRevsAutoconfirm['totalContentEdits'] ), |
| 575 | + array( APCOND_FR_CHECKEDEDITCOUNT, $wgFlaggedRevsAutoconfirm['totalCheckedEdits'] ) |
| 576 | + ) |
| 577 | + ); |
| 578 | + if ( $wgFlaggedRevsAutoconfirm['email'] ) { |
| 579 | + $wgAutopromote['autoreview'][] = array( APCOND_EMAILCONFIRMED ); |
| 580 | + } |
| 581 | + if ( $wgFlaggedRevsAutoconfirm['neverBlocked'] ) { |
| 582 | + $wgAutopromote['autoreview'][] = array( APCOND_FR_NEVERBOCKED ); |
| 583 | + } |
| 584 | + } |
563 | 585 | # Conditional API modules |
564 | 586 | efSetFlaggedRevsConditionalAPIModules(); |
565 | 587 | # Load hooks that aren't always set |
Index: trunk/extensions/FlaggedRevs/dataclasses/FRUserCounters.php |
— | — | @@ -4,7 +4,7 @@ |
5 | 5 | */ |
6 | 6 | class FRUserCounters { |
7 | 7 | /** |
8 | | - * Get params for a user |
| 8 | + * Get params for a user ID |
9 | 9 | * @param int $uid |
10 | 10 | * @param int $flags FR_MASTER, FR_FOR_UPDATE |
11 | 11 | * @param string $dBName, optional wiki name |
— | — | @@ -21,6 +21,21 @@ |
22 | 22 | } |
23 | 23 | |
24 | 24 | /** |
| 25 | + * Get params for a user |
| 26 | + * @param User $user |
| 27 | + * @return array|null |
| 28 | + */ |
| 29 | + public static function getParams( User $user ) { |
| 30 | + if ( $user->getId() ) { |
| 31 | + if ( !isset( $user->fr_user_params ) ) { // process cache... |
| 32 | + $user->fr_user_params = self::getUserParams( $user->getId() ); |
| 33 | + } |
| 34 | + return $user->fr_user_params; |
| 35 | + } |
| 36 | + return null; |
| 37 | + } |
| 38 | + |
| 39 | + /** |
25 | 40 | * Initializes unset param fields to their starting values |
26 | 41 | * @param &array $p |
27 | 42 | */ |
Index: trunk/extensions/FlaggedRevs/dataclasses/FlaggedRevs.hooks.php |
— | — | @@ -786,73 +786,60 @@ |
787 | 787 | } |
788 | 788 | |
789 | 789 | /** |
790 | | - * Grant implicit 'autoreview' group to users meeting the |
791 | | - * $wgFlaggedRevsAutoconfirm requirements. This lets people who |
792 | | - * opt-out as Editors still have their own edits automatically reviewed. |
| 790 | + * Check an autopromote condition that is defined by FlaggedRevs |
793 | 791 | * |
794 | 792 | * Note: some unobtrusive caching is used to avoid DB hits. |
795 | 793 | */ |
796 | | - public static function checkAutoPromote( $user, array &$promote ) { |
797 | | - global $wgFlaggedRevsAutoconfirm, $wgMemc; |
798 | | - $conds = $wgFlaggedRevsAutoconfirm; // convenience |
799 | | - if ( !is_array( $conds ) || !$user->getId() ) { |
800 | | - return true; // $wgFlaggedRevsAutoconfirm not applicable |
801 | | - } |
802 | | - $p = FRUserCounters::getUserParams( $user->getId() ); |
803 | | - $regTime = wfTimestampOrNull( TS_UNIX, $user->getRegistration() ); |
804 | | - if ( |
805 | | - # Check if user edited enough unique pages |
806 | | - $conds['uniqueContentPages'] > count( $p['uniqueContentPages'] ) || |
807 | | - # Check edit comment use |
808 | | - $conds['editComments'] > $p['editComments'] || |
809 | | - # Check user edit count |
810 | | - $conds['edits'] > $user->getEditCount() || |
811 | | - # Check account age |
812 | | - ( $regTime && $conds['days'] > ( ( time() - $regTime ) / 86400 ) ) || |
813 | | - # Check user email |
814 | | - $conds['email'] && !$user->isEmailConfirmed() || |
815 | | - # Don't grant to currently blocked users... |
816 | | - $user->isBlocked() |
817 | | - ) { |
818 | | - return true; |
819 | | - } |
820 | | - # Check if user edited enough content pages |
821 | | - $failedContentEdits = ( $conds['totalContentEdits'] > $p['totalContentEdits'] ); |
822 | | - |
823 | | - # Check if results are cached to avoid DB queries. |
824 | | - # Checked basic, already available, promotion heuristics first... |
825 | | - $APSkipKey = wfMemcKey( 'flaggedrevs', 'autoreview-skip', $user->getId() ); |
826 | | - if ( $wgMemc->get( $APSkipKey ) === 'true' ) { |
827 | | - return true; |
828 | | - } |
829 | | - # Check if user was ever blocked before |
830 | | - if ( $conds['neverBlocked'] && self::wasPreviouslyBlocked( $user ) ) { |
831 | | - $wgMemc->set( $APSkipKey, 'true', 3600 * 24 * 7 ); // cache results |
832 | | - return true; |
833 | | - } |
834 | | - # Check for edit spacing. This lets us know that the account has |
835 | | - # been used over N different days, rather than all in one lump. |
836 | | - if ( $conds['spacing'] > 0 && $conds['benchmarks'] > 1 ) { |
837 | | - $sTestKey = wfMemcKey( 'flaggedrevs', 'autoreview-spacing-ok', $user->getId() ); |
838 | | - # Hit the DB only if the result is not cached... |
839 | | - if ( $wgMemc->get( $sTestKey ) !== 'true' ) { |
840 | | - $pass = self::editSpacingCheck( $conds['spacing'], $conds['benchmarks'], $user ); |
841 | | - # Make a key to store the results |
842 | | - if ( $pass === true ) { |
843 | | - $wgMemc->set( $sTestKey, 'true', 7 * 24 * 3600 ); |
| 794 | + public static function checkAutoPromoteCond( $cond, array $params, User $user, &$result ) { |
| 795 | + global $wgMemc; |
| 796 | + switch( $cond ) { |
| 797 | + case APCOND_FR_EDITSUMMARYCOUNT: |
| 798 | + $p = FRUserCounters::getParams( $user ); |
| 799 | + $result = ( is_array( $p ) && $p['editComments'] >= $params[0] ); |
| 800 | + break; |
| 801 | + case APCOND_FR_NEVERBOCKED: |
| 802 | + $key = wfMemcKey( 'flaggedrevs', 'autopromote-blocked-ok', $user->getId() ); |
| 803 | + $val = $wgMemc->get( $key ); |
| 804 | + if ( $val === 'true' ) { |
| 805 | + $result = true; // passed |
| 806 | + } elseif ( $val === 'false' ) { |
| 807 | + $result = false; // failed |
844 | 808 | } else { |
845 | | - $wgMemc->set( $APSkipKey, 'true', $pass /* wait time */ ); |
846 | | - return true; |
| 809 | + # Hit the DB only if the result is not cached... |
| 810 | + $result = !self::wasPreviouslyBlocked( $user ); |
| 811 | + $wgMemc->set( $key, $result ? 'true' : 'false', 3600 * 24 * 7 ); // cache results |
847 | 812 | } |
848 | | - } |
| 813 | + break; |
| 814 | + case APCOND_FR_UNIQUEPAGECOUNT: |
| 815 | + $p = FRUserCounters::getParams( $user ); |
| 816 | + $result = ( is_array( $p ) && $p['uniqueContentPages'] >= $params[0] ); |
| 817 | + break; |
| 818 | + case APCOND_FR_EDITSPACING: |
| 819 | + $key = wfMemcKey( 'flaggedrevs', 'autopromote-spacing-ok', $user->getId() ); |
| 820 | + $val = $wgMemc->get( $key ); |
| 821 | + if ( $val === 'true' ) { |
| 822 | + $result = true; // passed |
| 823 | + } elseif ( $val === 'false' ) { |
| 824 | + $result = false; // failed |
| 825 | + } else { |
| 826 | + # Hit the DB only if the result is not cached... |
| 827 | + $pass = self::editSpacingCheck( $params[0], $params[1], $user ); |
| 828 | + # Make a key to store the results |
| 829 | + if ( $pass === true ) { |
| 830 | + $wgMemc->set( $key, 'true', 14 * 24 * 3600 ); |
| 831 | + } else { |
| 832 | + $wgMemc->set( $key, 'false', $pass /* wait time */ ); |
| 833 | + } |
| 834 | + } |
| 835 | + break; |
| 836 | + case APCOND_FR_CONTENTEDITCOUNT: |
| 837 | + $p = FRUserCounters::getParams( $user ); |
| 838 | + $result = ( is_array( $p ) && $p['totalContentEdits'] >= $params[0] ); |
| 839 | + break; |
| 840 | + case APCOND_FR_CHECKEDEDITCOUNT: |
| 841 | + $result = self::reviewedEditsCheck( $user, $params[0] ); |
| 842 | + break; |
849 | 843 | } |
850 | | - # Check implicitly checked edits |
851 | | - if ( $failedContentEdits && $conds['totalCheckedEdits'] > 0 ) { |
852 | | - if ( !self::reviewedEditsCheck( $user, $conds['totalCheckedEdits'] ) ) { |
853 | | - return true; |
854 | | - } |
855 | | - } |
856 | | - $promote[] = 'autoreview'; // add the group |
857 | 844 | return true; |
858 | 845 | } |
859 | 846 | |
Index: trunk/extensions/FlaggedRevs/FlaggedRevsDefines.php |
— | — | @@ -22,3 +22,13 @@ |
23 | 23 | define( 'FR_AUTOREVIEW_CHANGES', 1 ); |
24 | 24 | define( 'FR_AUTOREVIEW_CREATION', 2 ); |
25 | 25 | define( 'FR_AUTOREVIEW_CREATION_AND_CHANGES', FR_AUTOREVIEW_CHANGES | FR_AUTOREVIEW_CREATION ); |
| 26 | + |
| 27 | +# Autopromote conds (F=70,R=82) |
| 28 | +# @TODO: move these 5 to core |
| 29 | +define( 'APCOND_FR_EDITSUMMARYCOUNT', 70821 ); |
| 30 | +define( 'APCOND_FR_NEVERBOCKED', 70822 ); |
| 31 | +define( 'APCOND_FR_UNIQUEPAGECOUNT', 70823 ); |
| 32 | +define( 'APCOND_FR_EDITSPACING', 70824 ); |
| 33 | +define( 'APCOND_FR_CONTENTEDITCOUNT', 70825 ); |
| 34 | + |
| 35 | +define( 'APCOND_FR_CHECKEDEDITCOUNT', 70826 ); |