Completed
Push — master ( 0591cb...33c12c )
by
unknown
07:17
created

HtmlResponseParserRenderer::renderTextFor()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 73

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 73
ccs 44
cts 45
cp 0.9778
rs 8.589
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SCI\Specials\CitableMetadata;
4
5
use Onoi\Remi\ResponseParser;
6
use Html;
7
8
/**
9
 * @license GNU GPL v2+
10
 * @since 1.0
11
 *
12
 * @author mwjames
13
 */
14
class HtmlResponseParserRenderer {
15
16
	/**
17
	 * @var ResponseParser
18
	 */
19
	private $responseParser;
20
21
	/**
22
	 * @var boolean
23
	 */
24
	private $isReadOnly = false;
25
26
	/**
27
	 * @since 1.0
28
	 *
29
	 * @param ResponseParser $responseParser
30
	 */
31 3
	public function __construct( ResponseParser $responseParser ) {
32 3
		$this->responseParser = $responseParser;
33 3
	}
34
35
	/**
36
	 * @since 1.4
37
	 *
38
	 * @param boolean $isReadOnly
39
	 */
40
	public function isReadOnly( $isReadOnly ) {
41
		$this->isReadOnly = (bool)$isReadOnly;
42
	}
43
44
	/**
45
	 * @since 1.0
46
	 *
47
	 * @return string
48
	 */
49 1
	public function getRawResponse( $id ) {
50
51 1
		if ( $id === '' ) {
52
			return '';
53
		}
54
55 1
		return $this->responseParser->getRawResponse( $id );
56
	}
57
58
	/**
59
	 * @since 1.0
60
	 *
61
	 * @return string
62
	 */
63 1
	public function renderTextFor( $id ) {
64
65 1
		$html = '';
66
67 1
		$this->responseParser->doFilterResponseFor( $id );
68
69 1
		$html .= Html::rawElement(
70 1
			'div',
71
			[
72 1
				'id' => 'scite-status',
73 1
			],
74
			''
75 1
		);
76
77 1
		if ( $this->responseParser->getMessages() !== [] ) {
78
			return '';
79
		}
80
81 1
		$create = '';
82
83
		// Only display the create button for when the DB can be actually
84
		// accessed
85 1
		if ( $this->isReadOnly === false ) {
86 1
			$create = Html::element(
87 1
				'a',
88
				[
89 1
					'href' => '#',
90 1
					'class' => 'scite-create scite-action-button',
91 1
					'data-content-selector' => '#scite-record-content',
92 1
					'data-title' => $this->responseParser->getFilteredRecord()->getTitleForPageCreation()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Onoi\Remi\FilteredRecord as the method getTitleForPageCreation() does only exist in the following sub-classes of Onoi\Remi\FilteredRecord: SCI\FilteredMetadata\BibliographicFilteredRecord. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
93 1
				],
94 1
				wfMessage( 'sci-metadata-search-action-create' )->text()
95 1
			);
96 1
		}
97
98 1
		$html .= Html::rawElement(
99 1
			'div',
100
			[
101
				'class' => 'scite-metadata-search-action'
102 1
			],
103 1
			Html::element(
104 1
				'a',
105
				[
106 1
					'href' => '#',
107 1
					'class' => 'scite-highlight scite-action-button',
108
					'data-content-selector' => '#scite-record-content'
109 1
				],
110 1
				wfMessage( 'sci-metadata-search-action-highlight' )->text()
111 1
			) . '&nbsp;' . $create
112 1
		);
113
114
		// To display the #scite on the generated page
115 1
		$this->responseParser->getFilteredRecord()->set( '@show', 'true' );
116
117 1
		$html .= Html::rawElement(
118 1
			'div',
119
			[
120 1
				'id' => 'scite-record-content',
121
				'class' => 'scite-pre'
122 1
			],
123 1
			$this->responseParser->getFilteredRecord()->asSciteTransclusion()
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Onoi\Remi\FilteredRecord as the method asSciteTransclusion() does only exist in the following sub-classes of Onoi\Remi\FilteredRecord: SCI\FilteredMetadata\BibliographicFilteredRecord. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
124 1
		);
125
126 1
		$html .= Html::rawElement(
127 1
			'div',
128
			[
129
				'class' => 'visualClear'
130 1
			],
131
			''
132 1
		);
133
134 1
		return $html;
135
	}
136
137
}
138