Completed
Pull Request — master (#138)
by Tomáš
01:10
created

Serializer::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 12
cts 12
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 5
crap 2
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
            )
82
        );
83
84 4
        $comment = "{$firstIndent}/**\n";
85 4
        if ($text) {
86 4
            $comment .= "{$indent} * {$text}\n";
87
            $comment .= "{$indent} *\n";
88 4
        }
89
90
        $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment);
91
        $comment .= $indent . ' */';
92
93
        return $comment;
94
    }
95
96 4
    /**
97
     * @param $indent
98 4
     * @param $text
99
     * @return mixed
100
     */
101
    private function removeTrailingSpaces($indent, $text)
102
    {
103
        return str_replace("\n{$indent} * \n", "\n{$indent} *\n", $text);
104
    }
105
106 4
    /**
107
     * @param $indent
108 4
     * @param $text
109
     * @return mixed
110
     */
111
    private function addAsterisksForEachLine($indent, $text)
112
    {
113
        return str_replace("\n", "\n{$indent} * ", $text);
114
    }
115
116 4
    /**
117
     * @param DocBlock $docblock
118 4
     * @param $wrapLength
119 4
     * @return string
120 4
     */
121 1
    private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, $wrapLength)
122 1
    {
123
        $text = $docblock->getSummary() . ((string)$docblock->getDescription() ? "\n\n" . $docblock->getDescription()
124
                : '');
125 3
        if ($wrapLength !== null) {
126
            $text = wordwrap($text, $wrapLength);
127
            return $text;
128
        }
129
130
        return $text;
131
    }
132
133
    /**
134
     * @param DocBlock $docblock
135 4
     * @param $wrapLength
136
     * @param $indent
137 4
     * @param $comment
138 4
     * @return string
139 4
     */
140 1
    private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment)
141
    {
142
        foreach ($docblock->getTags() as $tag) {
143 4
            $tagText = $this->tagFormatter->format($tag);
144
            if ($wrapLength !== null) {
145 4
                $tagText = wordwrap($tagText, $wrapLength);
146
            }
147
148 4
            $tagText = str_replace("\n", "\n{$indent} * ", $tagText);
149
150
            $comment .= "{$indent} * {$tagText}\n";
151
        }
152
153
        return $comment;
154
    }
155
}
156