Completed
Pull Request — master (#102)
by Aleksei
14:20
created

Serializer::getDocComment()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 15
cts 15
cp 1
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 13
nc 4
nop 1
crap 3
1
<?php
2
/**
3
 * This file is part of phpDocumentor.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @copyright 2010-2015 Mike van Riel<[email protected]>
9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link      http://phpdoc.org
11
 */
12
13
namespace phpDocumentor\Reflection\DocBlock;
14
15
use phpDocumentor\Reflection\DocBlock;
16
use Webmozart\Assert\Assert;
17
18
/**
19
 * Converts a DocBlock back from an object to a complete DocComment including Asterisks.
20
 */
21
class Serializer
22
{
23
    /** @var string The string to indent the comment with. */
24
    protected $indentString = ' ';
25
26
    /** @var int The number of times the indent string is repeated. */
27
    protected $indent = 0;
28
29
    /** @var bool Whether to indent the first line with the given indent amount and string. */
30
    protected $isFirstLineIndented = true;
31
32
    /** @var int|null The max length of a line. */
33
    protected $lineLength = null;
34
35
    /** @var DocBlock\Tags\Formatter A custom tag formatter. */
36
    protected $tagFormatter = null;
37
38
    /**
39
     * Create a Serializer instance.
40
     *
41
     * @param int $indent The number of times the indent string is repeated.
42
     * @param string   $indentString    The string to indent the comment with.
43
     * @param bool     $indentFirstLine Whether to indent the first line.
44
     * @param int|null $lineLength The max length of a line or NULL to disable line wrapping.
45
     * @param DocBlock\Tags\Formatter $tagFormatter A custom tag formatter, defaults to PassthroughFormatter.
46
     */
47 8
    public function __construct($indent = 0, $indentString = ' ', $indentFirstLine = true, $lineLength = null, $tagFormatter = null)
48
    {
49 8
        Assert::integer($indent);
50 7
        Assert::string($indentString);
51 6
        Assert::boolean($indentFirstLine);
52 5
        Assert::nullOrInteger($lineLength);
53 4
        Assert::nullOrIsInstanceOf($tagFormatter, 'phpDocumentor\Reflection\DocBlock\Tags\Formatter');
54
55 4
        $this->indent = $indent;
56 4
        $this->indentString = $indentString;
57 4
        $this->isFirstLineIndented = $indentFirstLine;
58 4
        $this->lineLength = $lineLength;
59 4
        $this->tagFormatter = $tagFormatter ?: new DocBlock\Tags\Formatter\PassthroughFormatter();
60 4
    }
61
62
    /**
63
     * Generate a DocBlock comment.
64
     *
65
     * @param DocBlock $docblock The DocBlock to serialize.
66
     *
67
     * @return string The serialized doc block.
68
     */
69 4
    public function getDocComment(DocBlock $docblock)
70
    {
71 4
        $indent = str_repeat($this->indentString, $this->indent);
72 4
        $firstIndent = $this->isFirstLineIndented ? $indent : '';
73
        // 3 === strlen(' * ')
74 4
        $wrapLength = $this->lineLength ? $this->lineLength - strlen($indent) - 3 : null;
75
76 4
        $text = $this->removeTrailingSpaces(
77 4
            $indent,
78 4
            $this->addAsterisksForEachLine(
79 4
                $indent,
80 4
                $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength)
81 4
            )
82 4
        );
83
84 4
        $comment = "{$firstIndent}/**\n{$indent} * {$text}\n{$indent} *\n";
85 4
        $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment);
86 4
        $comment .= $indent . ' */';
87
88 4
        return $comment;
89
    }
90
91
    /**
92
     * @param $indent
93
     * @param $text
94
     * @return mixed
95
     */
96 4
    private function removeTrailingSpaces($indent, $text)
97
    {
98 4
        return str_replace("\n{$indent} * \n", "\n{$indent} *\n", $text);
99
    }
100
101
    /**
102
     * @param $indent
103
     * @param $text
104
     * @return mixed
105
     */
106 4
    private function addAsterisksForEachLine($indent, $text)
107
    {
108 4
        return str_replace("\n", "\n{$indent} * ", $text);
109
    }
110
111
    /**
112
     * @param DocBlock $docblock
113
     * @param $wrapLength
114
     * @return string
115
     */
116 4
    private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, $wrapLength)
117
    {
118 4
        $text = $docblock->getSummary() . ((string)$docblock->getDescription() ? "\n\n" . $docblock->getDescription()
119 4
                : '');
120 4
        if ($wrapLength !== null) {
121 1
            $text = wordwrap($text, $wrapLength);
122 1
            return $text;
123
        }
124 3
        return $text;
125
    }
126
127
    /**
128
     * @param DocBlock $docblock
129
     * @param $wrapLength
130
     * @param $indent
131
     * @param $comment
132
     * @return string
133
     */
134 4
    private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment)
135
    {
136 4
        foreach ($docblock->getTags() as $tag) {
137 4
            $tagText = $this->tagFormatter->format($tag);
138 4
            if ($wrapLength !== null) {
139 1
                $tagText = wordwrap($tagText, $wrapLength);
140 1
            }
141 4
            $tagText = str_replace("\n", "\n{$indent} * ", $tagText);
142
143 4
            $comment .= "{$indent} * {$tagText}\n";
144 4
        }
145
146 4
        return $comment;
147
    }
148
}
149