Test Failed
Push — master ( 9d4e41...1cd52c )
by Sebastian
03:24
created

Number::render()   C

Complexity

Conditions 13
Paths 44

Size

Total Lines 56
Code Lines 41

Duplication

Lines 30
Ratio 53.57 %

Importance

Changes 0
Metric Value
dl 30
loc 56
rs 6.6843
c 0
b 0
f 0
cc 13
eloc 41
nc 44
nop 2

How to fix   Long Method    Complexity   

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
 * citeproc-php
4
 *
5
 * @link        http://github.com/seboettg/citeproc-php for the source repository
6
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
7
 * @license     https://opensource.org/licenses/MIT
8
 */
9
10
namespace Seboettg\CiteProc\Rendering;
11
use Seboettg\CiteProc\CiteProc;
12
use Seboettg\CiteProc\Util;
13
use Seboettg\CiteProc\Styles\AffixesTrait;
14
use Seboettg\CiteProc\Styles\DisplayTrait;
15
use Seboettg\CiteProc\Styles\FormattingTrait;
16
use Seboettg\CiteProc\Styles\TextCaseTrait;
17
18
19
/**
20
 * Class Number
21
 * @package Seboettg\CiteProc\Rendering
22
 *
23
 * @author Sebastian Böttger <[email protected]>
24
 */
25
class Number implements RenderingInterface
26
{
27
28
    const RANGE_DELIMITER_HYPHEN = "-";
29
30
    const RANGE_DELIMITER_AMPERSAND = "&";
31
32
    const RANGE_DELIMITER_COMMA = ",";
33
34
    use FormattingTrait,
35
        AffixesTrait,
36
        TextCaseTrait,
37
        DisplayTrait;
38
39
    private $variable;
40
41
    private $form;
42
43
    public function __construct(\SimpleXMLElement $node)
44
    {
45
        //<number variable="edition" form="ordinal"/>
46
        /** @var \SimpleXMLElement $attribute */
47 View Code Duplication
        foreach ($node->attributes() as $attribute) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
48
            switch ($attribute->getName()) {
49
                case 'variable':
50
                    $this->variable = (string) $attribute;
51
                    break;
52
                case 'form':
53
                    $this->form = (string) $attribute;
54
            }
55
        }
56
57
        $this->initFormattingAttributes($node);
58
        $this->initAffixesAttributes($node);
59
        $this->initTextCaseAttributes($node);
60
    }
61
62
    /**
63
     * @param \stdClass $data
64
     * @param int|null $citationNumber
65
     * @return string
66
     */
67
    public function render($data, $citationNumber = null)
68
    {
69
        $lang = (isset($data->language) && $data->language != 'en') ? $data->language : 'en';
70
71
        if (empty($this->variable) || empty($data->{$this->variable})) {
72
            return "";
73
        }
74
        switch ($this->form) {
75 View Code Duplication
            case 'ordinal':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
76
                $var = $data->{$this->variable};
77
                if (preg_match("/\s*(\d+)\s*[\-\-\&,]\s*(\d+)\s*/", $var, $matches)) {
78
                    $num1 = self::ordinal($matches[1]);
79
                    $num2 = self::ordinal($matches[3]);
80
                    $text = $this->buildNumberRangeString($num1, $num2, $matches[2]);
81
                } else {
82
                    $text = self::ordinal($var);
83
                }
84
                break;
85 View Code Duplication
            case 'long-ordinal':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
                $var = $data->{$this->variable};
87
                if (preg_match("/\s*(\d+)\s*[\-\-\&,]\s*(\d+)\s*/", $var, $matches)) {
88
                    $num1 = self::longOrdinal($matches[1]);
89
                    $num2 = self::longOrdinal($matches[3]);
90
                    $text = $this->buildNumberRangeString($num1, $num2, $matches[2]);
91
                } else {
92
                    $text = self::longOrdinal($var);
93
                }
94
                break;
95 View Code Duplication
            case 'roman':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
                $var = $data->{$this->variable};
97
                if (preg_match("/\s*(\d+)\s*[\-\-\&,]\s*(\d+)\s*/", $var, $matches)) {
98
                    $num1 = Util\Number::dec2roman($matches[1]);
99
                    $num2 = Util\Number::dec2roman($matches[3]);
100
                    $text = $this->buildNumberRangeString($num1, $num2, $matches[2]);
101
                } else {
102
                    $text =  Util\Number::dec2roman($var);
103
                }
104
                break;
105
            case 'numeric':
106
            default:
107
                /*
108
                 During the extraction, numbers separated by a hyphen are stripped of intervening spaces (“2 - 4”
109
                 becomes “2-4”). Numbers separated by a comma receive one space after the comma (“2,3” and “2 , 3”
110
                 become “2, 3”), while numbers separated by an ampersand receive one space before and one after the
111
                 ampersand (“2&3” becomes “2 & 3”).
112
                 */
113
                $var = $data->{$this->variable};
114
                if (preg_match("/\s*(\d+)\s*[\-\-\&,]\s*(\d+)\s*/", $var, $matches)) {
115
                    $text = $this->buildNumberRangeString($matches[1], $matches[3], $matches[2]);
116
                } else {
117
                    $text =  Util\Number::dec2roman($var);
118
                }
119
                break;
120
        }
121
        return $this->wrapDisplayBlock($this->addAffixes($this->format($this->applyTextCase($text, $lang))));
122
    }
123
124
    public static function ordinal($num) {
125
        if (($num / 10) % 10 == 1) {
126
            $num .= CiteProc::getContext()->getLocale()->filter('terms', 'ordinal-04')->single;
127
        } elseif ($num % 10 == 1) {
128
            $num .= CiteProc::getContext()->getLocale()->filter('terms', 'ordinal-01')->single;
129
        } elseif ($num % 10 == 2) {
130
            $num .= CiteProc::getContext()->getLocale()->filter('terms', 'ordinal-02')->single;
131
        } elseif ($num % 10 == 3) {
132
            $num .= CiteProc::getContext()->getLocale()->filter('terms', 'ordinal-03')->single;
133
        } else {
134
            $num .= CiteProc::getContext()->getLocale()->filter('terms', 'ordinal-04')->single;
135
        }
136
        return $num;
137
    }
138
139
140
    public static function longOrdinal($num) {
141
        $num = sprintf("%02d", $num);
142
        $ret = CiteProc::getContext()->getLocale()->filter('terms', 'long-ordinal-' . $num)->single;
143
        if (!$ret) {
144
            return self::ordinal($num);
145
        }
146
        return $ret;
147
    }
148
149
    /**
150
     * @param string|int $num1
151
     * @param string|int $num2
152
     * @param string $delim
153
     * @return string
154
     */
155
    public function buildNumberRangeString($num1, $num2, $delim) {
156
157
        if (self::RANGE_DELIMITER_AMPERSAND === $delim) {
158
            $numRange = "$num1 " . self::RANGE_DELIMITER_AMPERSAND . " $num2";
159
        } else if (self::RANGE_DELIMITER_COMMA === $delim) {
160
            $numRange = $num1 . htmlentities(self::RANGE_DELIMITER_COMMA) . " $num2";
161
        } else  {
162
            $numRange = $num1 . self::RANGE_DELIMITER_HYPHEN . $num2;
163
        }
164
        return $numRange;
165
    }
166
167
168
169
}