CalendarController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Fabrica\Http\Api;
4
5
use Illuminate\Http\Request;
6
7
use Fabrica\Http\Requests;
8
use Fabrica\Http\Api\Controller;
9
use Fabrica\System\Eloquent\CalendarSingular;
10
11
use Fabrica\Utils\Lunar;
12
use Fabrica\Utils\CurlRequest;
13
14
class CalendarController extends Controller
15
{
16
    public function __construct()
17
    {
18
        $this->middleware('privilege:sys_admin');
19
        parent::__construct();
20
    }
21
22
    var $solar_special_days = [
23
        '0101' => '元旦',
24
        '0501' => '劳动',
25
        '1001' => '国庆',
26
    ];
27
28
    var $lunar_special_days = [
29
        '0101' => '春节',
30
        '0505' => '端午',
31
        '0815' => '中秋',
32
    ];
33
34
    /**
35
     * Display a listing of the resource.
36
     *
37
     * @return \Illuminate\Http\Response
38
     */
39
    public function index(Request $request, $year)
40
    {
41
        if ($year == 'current') {
42
            $year = date('Y');
43
        }
44
        if ($year > 2038 || $year < 1970) {
45
            throw new \UnexpectedValueException('the assigned year has error.', -16020);
46
        }
47
48
        $dates = $this->getYearDates(intval($year));
49
50
        return response()->json([ 'ecode' => 0, 'data' => $dates, 'options' => [ 'year' => date('Y'), 'date' => date('Y/m/d') ] ]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
51
    }
52
53
    /**
54
     * fetch the year dates .
55
     *
56
     * @param  number $year
57
     * @return array
58
     */
59
    public function getYearDates($year)
60
    {
61
        $year_singulars = [];
62
        $singulars = CalendarSingular::where('year', $year)->get();
63
        foreach ($singulars as $val)
64
        {
65
            $year_singulars[$val->date] = $val;
66
        }
67
68
        $dates = $this->getYearBasicDates($year);
69
        foreach ($dates as $key => $date)
70
        {
71
            if (!isset($year_singulars[$date['date']])) {
72
                continue;
73
            }
74
75
            $singular_date = $year_singulars[$date['date']];
76 View Code Duplication
            if (isset($singular_date['type']) && $singular_date['type']) {
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...
77
                $dates[$key]['type'] = $singular_date['type'];
78
            }
79
80 View Code Duplication
            if (isset($singular_date['target']) && $singular_date['target']) {
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...
81
                $dates[$key]['target'] = $singular_date['target'];
82
            }
83
        }
84
        return $dates;
85
    }
86
87
    /**
88
     * convert the solar to lunar.
89
     *
90
     * @param  number $year
91
     * @param  number $month
92
     * @param  number $day
93
     * @return array
94
     */
95
    private function convert2lunar($year, $month, $day)
96
    {
97
        $lunarObj = new Lunar();
98
        $lunar_info = $lunarObj->convertSolarToLunar($year, $month, $day);
99
100
        $lunar_date = sprintf('%02d', $lunar_info[4]) . sprintf('%02d', $lunar_info[5]);
101
102
        return [
103
            'year' => $lunar_info[3], 
104
            'month' => $lunar_info[1], 
105
            'day' => $lunar_info[2],
106
            'target' => isset($this->lunar_special_days[$lunar_date]) ? $this->lunar_special_days[$lunar_date] : '',
107
        ];
108
    }
109
110
    /**
111
     * get the whole year basic dates.
112
     *
113
     * @param  string $year
114
     * @return array
115
     */
116
    private function getYearBasicDates($year)
117
    {
118
        $dates = [];
119
        for ($i = 1; $i <= 12; $i++)
120
        {
121
            $mcnt = date('t', strtotime($year . '-' . $i . '-1'));
122
            for ($j = 1; $j <= $mcnt; $j++)
123
            {
124
                $lunar = $this->convert2lunar($year, $i, $j);
125
126
                $solar_date = sprintf('%02d', $i) . sprintf('%02d', $j);
127
                $w = intval(date('w', strtotime($year . '-' . $i . '-' . $j)));
128
129
                $dates[] = [
130
                    'date' => $year . '/' . sprintf('%02d', $i) . '/'. sprintf('%02d', $j),
131
                    'year' => $year,
132
                    'month' => $i,
133
                    'day' => $j,
134
                    'week' => $w == 0 ? 7 : $w,
135
                    'target' => isset($this->solar_special_days[$solar_date]) ? $this->solar_special_days[$solar_date] : '',
136
                    'lunar' => $lunar,
137
                ];
138
            }
139
        }
140
        return $dates;
141
    }
142
143
    public function update(Request $request)
144
    {
145
        $start_date = $request->input('start_date');
146
        if (!isset($start_date) || !$start_date) {
147
            throw new \UnexpectedValueException('the start date can not be empty.', -16021);
148
        }
149
150
        $end_date = $request->input('end_date');
151
        if (!isset($end_date) || !$end_date) {
152
            throw new \UnexpectedValueException('the end date can not be empty.', -16022);
153
        }
154
155
        $dates = [];
156
        $start_time = strtotime($start_date);
157
        $end_time = strtotime($end_date);
158
        for ($i = $start_time; $i <= $end_time; $i = $i + 3600 * 24)
159
        {
160
            $dates[] = date('Y/m/d', $i);
161
        }
162
        if (!$dates) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $dates of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
163
            throw new \UnexpectedValueException('the date range can not be empty.', -16023);
164
        }
165
166
        $mode = $request->input('mode');
167
        if (!isset($mode) || !$mode) {
168
            throw new \UnexpectedValueException('the operate mode can not be empty.', -16024);
169
        }
170
171
        if ($mode === 'set') {
172
            $type = $request->input('type');
173
            if (!isset($type) || !$type) {
174
                throw new \UnexpectedValueException('the setted type can not be empty.', -16025);
175
            }
176
            if (!in_array($type, [ 'holiday', 'workday' ])) {
177
                throw new \UnexpectedValueException('the setted type has error.', -16026);
178
            }
179
        }
180
181
        CalendarSingular::whereIn('date', $dates)->delete();
182
183
        if ($mode === 'set') {
184
            foreach ($dates as $date)
185
            {
186
                CalendarSingular::create(
187
                    [
188
                    'date' => $date,
189
                    'year' => intval(substr($date, 0, 4)),
190
                    'type' => $type
0 ignored issues
show
Bug introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
191
                    ]
192
                );
193
            }
194
        }
195
196
        return response()->json([ 'ecode' => 0, 'data' => $this->getYearDates(intval(substr($start_date, 0, 4)))]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
197
    }
198
199
    /**
200
     * sync the year singular calendars.
201
     *
202
     * @param   string $year
0 ignored issues
show
Bug introduced by
There is no parameter named $year. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
203
     * @@return array
204
     */
205
    public function sync(Request $request)
206
    {
207
        $year = $request->input('year');
208
        if (!isset($year) || !$year) {
209
            throw new \UnexpectedValueException('the sync year can not be empty.', -16027);
210
        }
211
212
        $year = intval($year);
213
214
        $url = 'http://www.actionview.cn:8080/actionview/api/holiday/' . $year;
215
216
        $res = CurlRequest::get($url);
217
        if (!isset($res['ecode']) || $res['ecode'] != 0) {
218
            throw new \UnexpectedValueException('failed to request the api.', -16028);
219
        }
220
221 View Code Duplication
        if (!isset($res['data']) || !$res['data']) {
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...
222
            throw new \UnexpectedValueException('the sync year data is empty.', -16029);
223
        }
224
225
        CalendarSingular::where('year', $year)->delete();
226
227
        $singulars = $res['data'];
228
        foreach ($singulars as $value) 
229
        {
230
            CalendarSingular::create(
231
                [
232
                'date' => $value['date'],
233
                'year' => $year,
234
                'type' => isset($value['holiday']) && $value['holiday'] ? 'holiday' : 'workday'
235
                ]
236
            );   
237
        }
238
239
        return response()->json([ 'ecode' => 0, 'data' => $this->getYearDates($year) ]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
240
    }
241
}
242