Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
27.91% |
12 / 43 |
|
25.00% |
1 / 4 |
CRAP | |
0.00% |
0 / 1 |
| Templating | |
27.91% |
12 / 43 |
|
25.00% |
1 / 4 |
139.40 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
| getUserLinks | |
69.23% |
9 / 13 |
|
0.00% |
0 / 1 |
5.73 | |||
| getContent | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
90 | |||
| getModeratedRevision | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace Flow; |
| 4 | |
| 5 | use Flow\Exception\FlowException; |
| 6 | use Flow\Exception\InvalidParameterException; |
| 7 | use Flow\Exception\PermissionException; |
| 8 | use Flow\Model\AbstractRevision; |
| 9 | use Flow\Model\PostRevision; |
| 10 | use Flow\Parsoid\ContentFixer; |
| 11 | use Flow\Repository\UserNameBatch; |
| 12 | use MediaWiki\Linker\Linker; |
| 13 | use MediaWiki\WikiMap\WikiMap; |
| 14 | |
| 15 | /** |
| 16 | * This class is slowly being deprecated. It used to house a minimalist |
| 17 | * php templating system, it is now just a few of the helpers that were |
| 18 | * reused in the new api responses and other parts of Flow. |
| 19 | */ |
| 20 | class Templating { |
| 21 | /** |
| 22 | * @var UserNameBatch |
| 23 | */ |
| 24 | private $usernames; |
| 25 | |
| 26 | /** |
| 27 | * @var RevisionActionPermissions |
| 28 | */ |
| 29 | private $permissions; |
| 30 | |
| 31 | /** |
| 32 | * @var ContentFixer |
| 33 | */ |
| 34 | private $contentFixer; |
| 35 | |
| 36 | /** |
| 37 | * @param UserNameBatch $usernames |
| 38 | * @param ContentFixer $contentFixer |
| 39 | * @param RevisionActionPermissions $permissions |
| 40 | */ |
| 41 | public function __construct( |
| 42 | UserNameBatch $usernames, |
| 43 | ContentFixer $contentFixer, |
| 44 | RevisionActionPermissions $permissions |
| 45 | ) { |
| 46 | $this->usernames = $usernames; |
| 47 | $this->contentFixer = $contentFixer; |
| 48 | $this->permissions = $permissions; |
| 49 | } |
| 50 | |
| 51 | /** |
| 52 | * Returns pretty-printed user links + user tool links for history and |
| 53 | * RecentChanges pages. |
| 54 | * |
| 55 | * Moderation-aware. |
| 56 | * |
| 57 | * @param AbstractRevision $revision Revision to display |
| 58 | * @return string HTML |
| 59 | * @throws PermissionException |
| 60 | */ |
| 61 | public function getUserLinks( AbstractRevision $revision ) { |
| 62 | if ( !$revision->isModerated() && !$this->permissions->isAllowed( $revision, 'history' ) ) { |
| 63 | throw new PermissionException( 'Insufficient permissions to see userlinks for rev_id = ' . |
| 64 | $revision->getRevisionId()->getAlphadecimal() ); |
| 65 | } |
| 66 | |
| 67 | // Convert to use MapCacheLRU? |
| 68 | // if this specific revision is moderated, its usertext can always be |
| 69 | // displayed, since it will be the moderator user |
| 70 | static $cache = []; |
| 71 | $userid = $revision->getUserId(); |
| 72 | $userip = $revision->getUserIp() ?? ''; |
| 73 | if ( isset( $cache[$userid][$userip] ) ) { |
| 74 | return $cache[$userid][$userip]; |
| 75 | } |
| 76 | $username = $this->usernames->get( WikiMap::getCurrentWikiId(), $userid, $userip ); |
| 77 | $cache[$userid][$userip] = $username ? |
| 78 | Linker::userLink( $userid, $username ) . Linker::userToolLinks( $userid, $username ) : |
| 79 | ''; |
| 80 | return $cache[$userid][$userip]; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Usually the revisions's content can just be displayed. In the event |
| 85 | * of moderation, however, that info should not be exposed. |
| 86 | * |
| 87 | * If a specific i18n message is available for a certain moderation level, |
| 88 | * that message will be returned (well, unless the user actually has the |
| 89 | * required permissions to view the full content). Otherwise, in normal |
| 90 | * cases, the full content will be returned. |
| 91 | * |
| 92 | * The content-type of the return value varies on the $format parameter. |
| 93 | * Further processing in the final output stage must escape all formats |
| 94 | * other than the default 'html' and 'fixed-html'. |
| 95 | * |
| 96 | * @param AbstractRevision $revision Revision to display content for |
| 97 | * @param string $format Format to output content in one of: |
| 98 | * (fixed-html|html|wikitext|topic-title-html|topic-title-wikitext|topic-title-plaintext) |
| 99 | * @return string HTML if requested, otherwise plain text |
| 100 | * @throws InvalidParameterException |
| 101 | */ |
| 102 | public function getContent( AbstractRevision $revision, $format = 'fixed-html' ) { |
| 103 | if ( !in_array( $format, [ 'fixed-html', 'html', 'wikitext', 'topic-title-html', |
| 104 | 'topic-title-wikitext', 'topic-title-plaintext' ] |
| 105 | ) |
| 106 | ) { |
| 107 | throw new InvalidParameterException( 'Invalid format: ' . $format ); |
| 108 | } |
| 109 | |
| 110 | $mainPermissionAction = ( $revision instanceof PostRevision && $revision->isTopicTitle() ) ? |
| 111 | 'view-topic-title' : |
| 112 | 'view'; |
| 113 | |
| 114 | $allowed = $this->permissions->isAllowed( $revision, $mainPermissionAction ); |
| 115 | // Posts require view access to the topic title as well |
| 116 | if ( $allowed && $revision instanceof PostRevision && !$revision->isTopicTitle() ) { |
| 117 | $allowed = $this->permissions->isAllowed( |
| 118 | $revision->getRootPost(), |
| 119 | 'view' |
| 120 | ); |
| 121 | } |
| 122 | |
| 123 | if ( !$allowed ) { |
| 124 | // failsafe - never output content if permissions aren't satisfied! |
| 125 | return ''; |
| 126 | } |
| 127 | |
| 128 | if ( $format === 'fixed-html' ) { |
| 129 | // Parsoid doesn't render redlinks & doesn't strip bad images |
| 130 | $content = $this->contentFixer->getContent( $revision ); |
| 131 | } else { |
| 132 | $content = $revision->getContent( $format ); |
| 133 | } |
| 134 | |
| 135 | return $content; |
| 136 | } |
| 137 | |
| 138 | public function getModeratedRevision( AbstractRevision $revision ) { |
| 139 | if ( $revision->isModerated() ) { |
| 140 | return $revision; |
| 141 | } else { |
| 142 | try { |
| 143 | return Container::get( 'collection.cache' )->getLastRevisionFor( $revision ); |
| 144 | } catch ( FlowException $e ) { |
| 145 | wfDebugLog( 'Flow', "Failed loading last revision for revid " . |
| 146 | $revision->getRevisionId()->getAlphadecimal() . " with collection id " . |
| 147 | $revision->getCollectionId()->getAlphadecimal() ); |
| 148 | throw $e; |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | } |