Completed
Push — master ( ab60f2...c901a1 )
by Ricardo
07:00
created

WikiController   F

Complexity

Total Complexity 199

Size/Duplication

Total Lines 1216
Duplicated Lines 26.89 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 199
lcom 1
cbo 4
dl 327
loc 1216
rs 0.8
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
B searchPath() 52 52 9
A getDirChildren() 9 20 4
B getDirTree() 9 39 7
B addChildren2Tree() 30 35 9
F index() 34 108 21
A create() 0 16 4
B createDoc() 0 59 10
B createFolder() 52 52 7
A checkin() 0 24 4
B checkout() 4 20 6
A getPathTreeDetail() 4 25 5
A getPathTree() 16 16 2
B show() 0 51 8
D update() 31 99 23
A recordVersion() 0 13 6
C copy() 0 76 13
D move() 25 83 19
B destroy() 11 30 7
B upload() 4 54 8
B remove() 4 28 6
A download2() 4 20 4
B download() 4 35 8
A downloadFolder() 0 28 3
A downloadFile() 11 11 2
A favorite() 23 23 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WikiController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WikiController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Fabrica\Http\Api;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Event;
7
8
use Fabrica\Http\Requests;
9
use Fabrica\Http\Api\Controller;
10
use Fabrica\Events\WikiEvent;
11
use Fabrica\Project\Eloquent\WikiFavorites;
12
use Fabrica\Utils\File;
13
use DB;
14
use MongoDB\BSON\ObjectID;
15
use Zipper;
16
17
class WikiController extends Controller
18
{
19
    /**
20
     * search path.
21
     * @param  \Illuminate\Http\Request  $request
22
     * @param  string  $project_key
23
     * @return \Illuminate\Http\Response
24
     */
25 View Code Duplication
    public function searchPath(Request $request, $project_key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
26
    {
27
        $s =  $request->input('s');
28
        if (!$s)
29
        {
30
            return Response()->json(['ecode' => 0, 'data' => []]);
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...
31
        }
32
33
        if ($s === '/')
34
        {
35
            return Response()->json(['ecode' => 0, 'data' => [ [ 'id' => '0', 'name' => '/' ] ] ]);
36
        }
37
38
        $query = DB::collection('wiki_' . $project_key)
39
            ->where('d', 1)
40
            ->where('del_flag', '<>', 1)
41
            ->where('name', 'like', '%' . $s . '%');
42
43
        $moved_path = $request->input('moved_path');
44
        if (isset($moved_path) && $moved_path)
45
        {
46
            $query->where('pt', '<>', $moved_path);
47
            $query->where('_id', '<>', $moved_path);
48
        }
49
50
        $directories = $query->take(20)->get(['name', 'pt']);
51
52
        $ret = [];
53
        foreach ($directories as $d)
54
        {
55
            $parents = [];
56
            $path = '';
57
            $ps = DB::collection('wiki_' . $project_key)
58
                ->whereIn('_id', $d['pt'])
59
                ->get([ 'name' ]);
60
            foreach ($ps as $val)
61
            {
62
                $parents[$val['_id']->__toString()] = $val['name'];
63
            }
64
65
            foreach ($d['pt'] as $pid)
66
            {
67
                if (isset($parents[$pid]))
68
                {
69
                    $path .= '/' . $parents[$pid];
70
                }
71
            }
72
            $path .= '/' . $d['name'];
73
            $ret[] = [ 'id' => $d['_id']->__toString(), 'name' => $path ];
74
        }
75
        return Response()->json(['ecode' => 0, 'data' => parent::arrange($ret)]);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (arrange() instead of searchPath()). Are you sure this is correct? If so, you might want to change this to $this->arrange().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
76
    }
77
78
    /**
79
     * get the directory children.
80
     * @param  string  $project_key
81
     * @param  string  $directory
82
     * @return \Illuminate\Http\Response
83
     */
84
    public function getDirChildren(Request $request, $project_key, $directory)
85
    {
86
        $sub_dirs = DB::collection('wiki_' . $project_key)
87
            ->where('parent', $directory)
88
            ->where('del_flag', '<>', 1)
89
            ->get();
90
91
        $res = [];
92 View Code Duplication
        foreach ($sub_dirs as $val)
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...
93
        {
94
            $res[] = [ 
95
                'id' => $val['_id']->__toString(), 
96
                'name' => $val['name'],
97
                'd' => isset($val['d']) ? $val['d'] : 0, 
98
                'parent' => isset($val['parent']) ? $val['parent'] : '' 
99
            ];
100
        }
101
102
        return Response()->json([ 'ecode' => 0, 'data' => $res ]);
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...
103
    }
104
105
    /**
106
     * get the directory tree.
107
     * @param  string  $project_key
108
     * @return \Illuminate\Http\Response
109
     */
110
    public function getDirTree(Request $request, $project_key)
111
    {
112
        $dt = [ 'id' => '0', 'name' => '根目录', 'd' => 1 ];
113
114
        $curnode = $request->input('currentnode');
115
        if (!$curnode)
116
        {
117
            $curnode = '0';
118
        }
119
120
        $pt = [ '0' ];
121
        if ($curnode !== '0')
122
        {
123
            $node = DB::collection('wiki_' . $project_key)
124
                ->where('_id', $curnode)
125
                ->first();
126
127
            if ($node)
128
            {
129
                $pt = $node['pt'];
130
                if (isset($node['d']) && $node['d'] == 1) 
131
                {
132
                    array_push($pt, $curnode);
133
                }
134
            }
135
        }
136
137 View Code Duplication
        foreach($pt as $val)
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...
138
        {
139
            $sub_dirs = DB::collection('wiki_' . $project_key)
140
                ->where('parent', $val)
141
                ->where('del_flag', '<>', 1)
142
                ->get();
143
144
            $this->addChildren2Tree($dt, $val, $sub_dirs);
145
        }
146
147
        return Response()->json([ 'ecode' => 0, 'data' => $dt ]);
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...
148
    }
149
150
    /**
151
     * add children to tree.
152
     *
153
     * @param  array  $dt
154
     * @param  string $parent_id
155
     * @param  array  $sub_dirs
156
     * @return void
157
     */
158
    public function addChildren2Tree(&$dt, $parent_id, $sub_dirs)
159
    {
160
        $new_dirs = [];
161 View Code Duplication
        foreach($sub_dirs as $val)
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...
162
        {
163
            $new_dirs[] = [ 
164
                'id' => $val['_id']->__toString(), 
165
                'name' => $val['name'], 
166
                'd' => isset($val['d']) ? $val['d'] : 0, 
167
                'parent' => isset($val['parent']) ? $val['parent'] : '' 
168
            ];
169
        }
170
171 View Code Duplication
        if ($dt['id'] == $parent_id)
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...
172
        {
173
            $dt['children'] = $new_dirs;
174
            return true;
175
        }
176
        else
177
        {
178
            if (isset($dt['children']) && $dt['children'])
179
            {
180
                $children_num = count($dt['children']);
181
                for ($i = 0; $i < $children_num; $i++)
182
                {
183
                    $res = $this->addChildren2Tree($dt['children'][$i], $parent_id, $sub_dirs);
184
                    if ($res === true)
185
                    {
186
                        return true;
187
                    }
188
                }
189
            }
190
            return false;
191
        }
192
    }
193
194
    /**
195
     * Display a listing of the resource.
196
     *
197
     * @return \Illuminate\Http\Response
198
     */
199
    public function index(Request $request, $project_key, $directory)
200
    {
201
        $documents = [];
0 ignored issues
show
Unused Code introduced by
$documents is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
202
        $mode = 'list';
203
        $query = DB::collection('wiki_' . $project_key);
204
205
        $name = $request->input('name');
206 View Code Duplication
        if (isset($name) && $name)
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...
207
        {
208
            $mode = 'search';
209
            $query = $query->where('name', 'like', '%' . $name . '%');
210
        }
211
212
        $updated_at = $request->input('updated_at');
213
        if (isset($updated_at) && $updated_at)
214
        {
215
            $mode = 'search';
216
            $query->where(function ($query) use ($updated_at) {
217
                $unitMap = [ 'w' => 'week', 'm' => 'month', 'y' => 'year' ];
218
                $unit = substr($updated_at, -1);
219
                $val = abs(substr($updated_at, 0, -1));
220
                $query->where('created_at', '>=', strtotime(date('Ymd', strtotime('-' . $val . ' ' . $unitMap[$unit]))))
221
                    ->orwhere('updated_at', '>=', strtotime(date('Ymd', strtotime('-' . $val . ' ' . $unitMap[$unit]))));
222
            });
223
        }
224
225
        $favorite_wikis = WikiFavorites::where('project_key', $project_key)
226
            ->where('user.id', $this->user->id)
227
            ->get()
228
            ->toArray();
229
        $favorite_dids = array_column($favorite_wikis, 'wid');
230
231
        $myfavorite = $request->input('myfavorite');
232 View Code Duplication
        if (isset($myfavorite) && $myfavorite == '1')
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...
233
        {
234
            $mode = 'search';
235
            $favoritedIds = [];
236
            foreach ($favorite_dids as $did)
237
            {
238
                $favoritedIds[] = new ObjectID($did);
239
            }
240
241
            $query->whereIn('_id', $favoritedIds);
242
        }
243
244 View Code Duplication
        if ($directory !== '0')
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...
245
        {
246
            $query = $query->where($mode === 'search' ? 'pt' : 'parent', $directory);
247
        }
248
        else
249
        {
250
            if ($mode === 'list')
251
            {
252
                $query = $query->where('parent', $directory);
253
            }
254
        }
255
256
        $query->where('del_flag', '<>', 1);
257
        $query->orderBy('d', 'desc')->orderBy('_id', 'desc');
258
259
        $limit = 1000; // fix me
260
        $query->take($limit);
261
        $documents = $query->get();
262
263
        $favorite_wikis = WikiFavorites::where('project_key', $project_key)
264
            ->where('user.id', $this->user->id)
265
            ->get()
266
            ->toArray();
267
        $favorite_wids = array_column($favorite_wikis, 'wid');
268
269 View Code Duplication
        foreach ($documents as $k => $d)
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...
270
        {
271
            if (in_array($d['_id']->__toString(), $favorite_wids))
272
            {
273
                $documents[$k]['favorited'] = true;
274
            }
275
        }
276
277
        $path = [];
278
        $home = [];
279
        if ($directory === '0')
280
        {
281
            $path[] = [ 'id' => '0', 'name' => 'root' ];
282
            if ($mode === 'list')
283
            {
284
                foreach ($documents as $doc)
285
                {
286
                    if ((!isset($doc['d']) || $doc['d'] != 1) && strtolower($doc['name']) === 'home')
287
                    {
288
                        $home = $doc;
289
                    }
290
                }
291
            }
292
        }
293
        else
294
        {
295
            $d = DB::collection('wiki_' . $project_key)
296
                ->where('_id', $directory)
297
                ->first();
298
            if ($d && isset($d['pt']))
299
            {
300
                $path = $this->getPathTreeDetail($project_key, $d['pt']);
301
            }
302
            $path[] = [ 'id' => $directory, 'name' => $d['name'] ];
303
        }
304
305
        return Response()->json([ 'ecode' => 0, 'data' => parent::arrange($documents), 'options' => [ 'path' => $path, 'home' => parent::arrange($home) ] ]);
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...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (arrange() instead of index()). Are you sure this is correct? If so, you might want to change this to $this->arrange().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
306
    }
307
308
    /**
309
     * Store a newly created resource in storage.
310
     *
311
     * @param  \Illuminate\Http\Request  $request
312
     * @param  string  $project_key
313
     * @return \Illuminate\Http\Response
314
     */
315
    public function create(Request $request, $project_key)
316
    {
317
        $d =  $request->input('d');
318
        if (isset($d) && $d == 1)
319
        {
320
            if (!$this->isPermissionAllowed($project_key, 'manage_project'))
321
            {
322
                return Response()->json(['ecode' => -10002, 'emsg' => 'permission denied.']);
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...
323
            }
324
            return $this->createFolder($request, $project_key);
325
        }
326
        else
327
        {
328
            return $this->createDoc($request, $project_key);
329
        }
330
    }
331
332
    /**
333
     * Store a newly created resource in storage.
334
     *
335
     * @param  \Illuminate\Http\Request  $request
336
     * @param  string  $project_key
337
     * @return \Illuminate\Http\Response
338
     */
339
    public function createDoc(Request $request, $project_key)
340
    {
341
        $insValues = [];
342
343
        $parent = $request->input('parent');
344
        if (!isset($parent))
345
        {
346
            throw new \UnexpectedValueException('the parent directory can not be empty.', -11950);
347
        }
348
        $insValues['parent'] = $parent;
349
350
        if ($parent !== '0')
351
        {
352
            $isExists = DB::collection('wiki_' . $project_key)
353
                ->where('_id', $parent)
354
                ->where('d', 1)
355
                ->where('del_flag', '<>', 1)
356
                ->exists();
357
            if (!$isExists)
358
            {
359
                throw new \UnexpectedValueException('the parent directory does not exist.', -11951);
360
            }
361
        }
362
363
        $name = $request->input('name');
364
        if (!isset($name) || !$name)
365
        {
366
            throw new \UnexpectedValueException('the name can not be empty.', -11952);
367
        }
368
        $insValues['name'] = $name;
369
370
        $isExists = DB::collection('wiki_' . $project_key)
371
            ->where('parent', $parent)
372
            ->where('name', $name)
373
            ->where('d', '<>', 1)
374
            ->where('del_flag', '<>', 1)
375
            ->exists();
376
        if ($isExists)
377
        {
378
            throw new \UnexpectedValueException('the name cannot be repeated.', -11953);
379
        }
380
381
        $contents = $request->input('contents');
382
        if (isset($contents) && $contents)
383
        {
384
            $insValues['contents'] = $contents;
385
        }
386
387
        $insValues['pt'] = $this->getPathTree($project_key, $parent);
388
        $insValues['version'] = 1;
389
        $insValues['creator'] = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
390
        $insValues['created_at'] = time();
391
        $id = DB::collection('wiki_' . $project_key)->insertGetId($insValues);
392
393
        $isSendMsg = $request->input('isSendMsg') && true;
394
        Event::fire(new WikiEvent($project_key, $insValues['creator'], [ 'event_key' => 'create_wiki', 'isSendMsg' => $isSendMsg, 'data' => [ 'wiki_id' => $id->__toString() ] ]));
395
396
        return $this->show($request, $project_key, $id);
397
    }
398
399
    /**
400
     * Store a newly created resource in storage.
401
     *
402
     * @param  \Illuminate\Http\Request  $request
403
     * @param  string  $project_key
404
     * @return \Illuminate\Http\Response
405
     */
406 View Code Duplication
    public function createFolder(Request $request, $project_key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
407
    {
408
        $insValues = [];
409
410
        $parent = $request->input('parent');
411
        if (!isset($parent))
412
        {
413
            throw new \UnexpectedValueException('the parent directory can not be empty.', -11950);
414
        }
415
        $insValues['parent'] = $parent;
416
417
        if ($parent !== '0')
418
        {
419
            $isExists = DB::collection('wiki_' . $project_key)
420
                ->where('_id', $parent)
421
                ->where('d', 1)
422
                ->where('del_flag', '<>', 1)
423
                ->exists();
424
            if (!$isExists)
425
            {
426
                throw new \UnexpectedValueException('the parent directory does not exist.', -11951);
427
            }
428
        }
429
430
        $name =  $request->input('name');
431
        if (!isset($name) || !$name)
432
        {
433
            throw new \UnexpectedValueException('the name can not be empty.', -11952);
434
        }
435
        $insValues['name'] = $name;
436
437
        $isExists = DB::collection('wiki_' . $project_key)
438
            ->where('parent', $parent)
439
            ->where('name', $name)
440
            ->where('d', 1)
441
            ->where('del_flag', '<>', 1)
442
            ->exists();
443
        if ($isExists)
444
        {
445
            throw new \UnexpectedValueException('the name cannot be repeated.', -11953);
446
        }
447
448
        $insValues['pt'] = $this->getPathTree($project_key, $parent);
449
        $insValues['d'] = 1;
450
        $insValues['creator'] = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
451
        $insValues['created_at'] = time();
452
453
        $id = DB::collection('wiki_' . $project_key)->insertGetId($insValues);
454
455
        $document = DB::collection('wiki_' . $project_key)->where('_id', $id)->first();
456
        return Response()->json(['ecode' => 0, 'data' => parent::arrange($document)]);
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...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (arrange() instead of createFolder()). Are you sure this is correct? If so, you might want to change this to $this->arrange().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
457
    }
458
459
    /**
460
     * check in the wiki.
461
     * @param  string  $project_key
462
     * @param  string  $id
463
     * @return array
464
     */
465
    public function checkin(Request $request, $project_key, $id)
466
    {
467
        $document = DB::collection('wiki_' . $project_key)
468
            ->where('_id', $id)
469
            ->where('del_flag', '<>', 1)
470
            ->first();
471
        if (!$document)
472
        {
473
            throw new \UnexpectedValueException('the object does not exist.', -11954);
474
        }
475
476
        if (isset($document['checkin']) && $document['checkin'])
477
        {
478
            throw new \UnexpectedValueException('the object has been locked.', -11955);
479
        }
480
481
        $checkin = []; 
482
        $checkin['user'] = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
483
        $checkin['at'] = time();
484
485
        DB::collection('wiki_' . $project_key)->where('_id', $id)->update(['checkin' => $checkin]);
486
487
        return $this->show($request, $project_key, $id);
488
    }
489
490
    /**
491
     * check out the wiki.
492
     * @param  string  $project_key
493
     * @param  string  $id
494
     * @return array
495
     */
496
    public function checkout(Request $request, $project_key, $id)
497
    {
498
        $document = DB::collection('wiki_' . $project_key)
499
            ->where('_id', $id)
500
            ->where('del_flag', '<>', 1)
501
            ->first();
502
        if (!$document)
503
        {
504
            throw new \UnexpectedValueException('the object does not exist.', -11954);
505
        }
506
507 View Code Duplication
        if (isset($document['checkin']) && !((isset($document['checkin']['user']) && $document['checkin']['user']['id'] == $this->user->id) || $this->isPermissionAllowed($project_key, 'manage_project')))
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...
508
        {
509
            throw new \UnexpectedValueException('the object cannot been unlocked.', -11956);
510
        }
511
512
        DB::collection('wiki_' . $project_key)->where('_id', $id)->unset('checkin');
513
514
        return $this->show($request, $project_key, $id);
515
    }
516
517
    /**
518
     * get parent treee.
519
     * @param  string  $project_key
520
     * @param  array  $pt
521
     * @return array
522
     */
523
    public function getPathTreeDetail($project_key, $pt)
524
    {
525
        $parents = [];
526
        $ps = DB::collection('wiki_' . $project_key)
527
            ->whereIn('_id', $pt)
528
            ->get([ 'name' ]);
529
        foreach ($ps as $val)
530
        {
531
            $parents[$val['_id']->__toString()] = $val['name'];
532
        }
533
534
        $path = [];
535
        foreach ($pt as $pid)
536
        {
537
            if ($pid === '0')
538
            {
539
                $path[] = [ 'id' => '0', 'name' => 'root' ];
540
            }
541 View Code Duplication
            else if (isset($parents[$pid]))
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...
542
            {
543
                $path[] = [ 'id' => $pid, 'name' => $parents[$pid] ];
544
            }
545
        }
546
        return $path;
547
    }
548
549
    /**
550
     * get parent treee.
551
     * @param  string  $project_key
552
     * @param  string  $directory
553
     * @return array
554
     */
555 View Code Duplication
    public function getPathTree($project_key, $directory)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
556
    {
557
        $pt = [];
0 ignored issues
show
Unused Code introduced by
$pt is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
558
        if ($directory === '0')
559
        {
560
            $pt = [ '0' ];
561
        }
562
        else
563
        {
564
            $d = DB::collection('wiki_' . $project_key)
565
                ->where('_id', $directory)
566
                ->first();
567
            $pt = array_merge($d['pt'], [ $directory ]);
568
        }
569
        return $pt;
570
    }
571
572
    /**
573
     * get the specified resource.
574
     *
575
     * @param  \Illuminate\Http\Request  $request
576
     * @param  string  $project_key
577
     * @param  string  $id
578
     * @return \Illuminate\Http\Response
579
     */
580
    public function show(Request $request, $project_key, $id)
581
    {
582
        $document = DB::collection('wiki_' . $project_key)
583
            ->where('_id', $id)
584
            ->where('del_flag', '<>', 1)
585
            ->first();
586
        if (!$document)
587
        {
588
            throw new \UnexpectedValueException('the object does not exist.', -11954);
589
        }
590
591
        if (WikiFavorites::where('wid', $id)->where('user.id', $this->user->id)->exists())
592
        {
593
            $document['favorited'] = true;
594
        }
595
596
        $newest = [];
597
        $newest['name']       = $document['name'];
598
        $newest['editor']     = isset($document['editor']) ? $document['editor'] : $document['creator'];
599
        $newest['updated_at'] = isset($document['updated_at']) ? $document['updated_at'] : $document['created_at'];
600
        $newest['version']    = $document['version'];
601
602
        $v =  $request->input('v');
603
        if (isset($v) && intval($v) != $document['version'])
604
        {
605
            $w = DB::collection('wiki_version_' . $project_key)
606
                ->where('wid', $id)
607
                ->where('version', intval($v)) 
608
                ->first();
609
            if (!$w)
610
            {
611
                throw new \UnexpectedValueException('the version does not exist.', -11957);
612
            }
613
614
            $document['name']       = $w['name'];
615
            $document['contents']   = $w['contents'];
616
            $document['editor']     = $w['editor'];
617
            $document['updated_at'] = $w['updated_at'];
618
            $document['version']    = $w['version'];
619
        }
620
        
621
        $document['versions'] = DB::collection('wiki_version_' . $project_key)
622
            ->where('wid', $id)
623
            ->orderBy('_id', 'desc')
624
            ->get(['name', 'editor', 'updated_at', 'version']);
625
        array_unshift($document['versions'], $newest);
626
627
        $path = $this->getPathTreeDetail($project_key, $document['pt']);
628
629
        return Response()->json(['ecode' => 0, 'data' => parent::arrange($document), 'options' => [ 'path' => $path ]]);
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...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (arrange() instead of show()). Are you sure this is correct? If so, you might want to change this to $this->arrange().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
630
    }
631
632
    /**
633
     * Update the specified resource in storage.
634
     *
635
     * @param  \Illuminate\Http\Request  $request
636
     * @param  string  $project_key
637
     * @param  string  $id
638
     * @return \Illuminate\Http\Response
639
     */
640
    public function update(Request $request, $project_key, $id)
641
    {
642
        $name =  $request->input('name');
643
        if (!isset($name) || !$name)
644
        {
645
            throw new \UnexpectedValueException('the name can not be empty.', -11952);
646
        }
647
648
        $old_document = DB::collection('wiki_' . $project_key)
649
            ->where('_id', $id)
650
            ->where('del_flag', '<>', 1)
651
            ->first();
652
        if (!$old_document)
653
        {
654
            throw new \UnexpectedValueException('the object does not exist.', -11954);
655
        }
656
657
        if (isset($old_document['d']) && $old_document['d'] === 1)
658
        {
659
            if (!$this->isPermissionAllowed($project_key, 'manage_project')) 
660
            {
661
                return Response()->json(['ecode' => -10002, 'emsg' => 'permission denied.']);
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...
662
            }
663
        }
664 View Code Duplication
        else
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...
665
        {
666
            if (isset($old_document['checkin']) && isset($old_document['checkin']['user']) && $old_document['checkin']['user']['id'] !== $this->user->id)
667
            {
668
                throw new \UnexpectedValueException('the object has been locked.', -11955);
669
            }
670
        }
671
672
        $updValues = [];
673 View Code Duplication
        if ($old_document['name'] !== $name)
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...
674
        {
675
            $query = DB::collection('wiki_' . $project_key)
676
                ->where('parent', $old_document['parent'])
677
                ->where('name', $name)
678
                ->where('del_flag', '<>', 1);
679
680
            if (isset($old_document['d']) && $old_document['d'] === 1)
681
            {
682
                $query->where('d', 1);
683
            }
684
            else
685
            {
686
                $query->where('d', '<>', 1);
687
            }
688
689
            $isExists = $query->exists();
690
            if ($isExists)
691
            {
692
                throw new \UnexpectedValueException('the name cannot be repeated.', -11953);
693
            }
694
695
            $updValues['name'] = $name;
696
        }
697
698
        if (!isset($old_document['d']) || $old_document['d'] !== 1)
699
        {
700
            $contents = $request->input('contents');
701
            if (isset($contents) && $contents)
702
            {
703
                $updValues['contents'] = $contents;
704
            }
705
706
            if (isset($old_document['version']) && $old_document['version'])
707
            {
708
                $updValues['version'] = $old_document['version'] + 1;
709
            }
710
            else
711
            {
712
                $updValues['version'] = 2;
713
            }
714
        }
715
        
716
        $updValues['editor'] = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
717
        $updValues['updated_at'] = time();
718
        DB::collection('wiki_' . $project_key)->where('_id', $id)->update($updValues);
719
720
        // record the version
721
        if (!isset($old_document['d']) || $old_document['d'] !== 1)
722
        {
723
            // unlock the wiki
724
            DB::collection('wiki_' . $project_key)->where('_id', $id)->unset('checkin'); 
725
            // record versions 
726
            $this->recordVersion($project_key, $old_document);
727
728
            $isSendMsg = $request->input('isSendMsg') && true;
729
            Event::fire(new WikiEvent($project_key, $updValues['editor'], [ 'event_key' => 'edit_wiki', 'isSendMsg' => $isSendMsg, 'data' => [ 'wiki_id' => $id ] ]));
730
731
            return $this->show($request, $project_key, $id);
732
        }
733
        else
734
        {
735
            $document = DB::collection('wiki_' . $project_key)->where('_id', $id)->first();
736
            return Response()->json(['ecode' => 0, 'data' => parent::arrange($document)]);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (arrange() instead of update()). Are you sure this is correct? If so, you might want to change this to $this->arrange().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
737
        }
738
    }
739
740
    /**
741
     * record the last version.
742
     *
743
     * @param  array  $document
744
     * @return \Illuminate\Http\Response
745
     */
746
    public function recordVersion($project_key, $document)
747
    {
748
        $insValues = [];
749
750
        $insValues['wid']         = $document['_id']->__toString();
751
        $insValues['name']        = isset($document['name']) ? $document['name'] : '';
752
        $insValues['contents']    = isset($document['contents']) ? $document['contents'] : '';
753
        $insValues['version']     = isset($document['version']) ? $document['version'] : 1;
754
        $insValues['editor']      = isset($document['editor']) ? $document['editor'] : $document['creator'];
755
        $insValues['updated_at']  = isset($document['updated_at']) ? $document['updated_at'] : $document['created_at'];
756
757
        DB::collection('wiki_version_' . $project_key)->insert($insValues);
758
    }
759
760
    /**
761
     * copy the document.
762
     * @param  \Illuminate\Http\Request  $request
763
     * @param  string  $project_key
764
     * @return \Illuminate\Http\Response
765
     */
766
    public function copy(Request $request, $project_key)
767
    {
768
        $id =  $request->input('id');
769
        if (!isset($id) || !$id)
770
        {
771
            throw new \UnexpectedValueException('the copy object can not be empty.', -11960);
772
        }
773
774
        $name =  $request->input('name');
775
        if (!isset($name) || !$name)
776
        {
777
            throw new \UnexpectedValueException('the name can not be empty.', -11952);
778
        }
779
780
        $dest_path =  $request->input('dest_path');
781
        if (!isset($dest_path))
782
        {
783
            throw new \UnexpectedValueException('the dest directory can not be empty.', -11961);
784
        }
785
786
        $document = DB::collection('wiki_' . $project_key)
787
            ->where('_id', $id)
788
            ->where('d', '<>', 1)
789
            ->where('del_flag', '<>', 1)
790
            ->first();
791
        if (!$document)
792
        {
793
            throw new \UnexpectedValueException('the copy object does not exist.', -11962);
794
        }
795
796
        $dest_directory = [];
797
        if ($dest_path !== '0')
798
        {
799
            $dest_directory = DB::collection('wiki_' . $project_key)
800
                ->where('_id', $dest_path)
801
                ->where('d', 1)
802
                ->where('del_flag', '<>', 1)
803
                ->first();
804
            if (!$dest_directory)
805
            {
806
                throw new \UnexpectedValueException('the dest directory does not exist.', -11963);
807
            }
808
        }
809
810
        $isExists = DB::collection('wiki_' . $project_key)
811
            ->where('parent', $dest_path)
812
            ->where('name', $name)
813
            ->where('d', '<>', 1)
814
            ->where('del_flag', '<>', 1)
815
            ->exists();
816
        if ($isExists)
817
        {
818
            throw new \UnexpectedValueException('the name cannot be repeated.', -11953);
819
        }
820
821
        $insValues = [];
822
        $insValues['name'] = $name;
823
        $insValues['parent'] = $dest_path;
824
        $insValues['pt'] = array_merge(isset($dest_directory['pt']) ? $dest_directory['pt'] : [], [$dest_path]);
825
826
        //$insValues['size']    = $document['size'];
827
        //$insValues['type']    = $document['type'];
828
        //$insValues['index']   = $document['index'];
829
830
        $insValues['version'] = 1;
831
        $insValues['contents'] = isset($document['contents']) ? $document['contents'] : '';
832
        $insValues['attachments'] = isset($document['attachments']) ? $document['attachments'] : [];
833
            
834
        $insValues['creator'] = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
835
        $insValues['created_at'] = time();
836
837
        $new_id = DB::collection('wiki_' . $project_key)->insertGetId($insValues);         
838
839
        $document = DB::collection('wiki_' . $project_key)->where('_id', $new_id)->first();
840
        return Response()->json(['ecode' => 0, 'data' => parent::arrange($document)]);
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...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (arrange() instead of copy()). Are you sure this is correct? If so, you might want to change this to $this->arrange().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
841
    }
842
843
    /**
844
     * move the document.
845
     *
846
     * @param  \Illuminate\Http\Request  $request
847
     * @param  string  $project_key
848
     * @return \Illuminate\Http\Response
849
     */
850
    public function move(Request $request, $project_key)
851
    {
852
        $id =  $request->input('id');
853
        if (!isset($id) || !$id)
854
        {
855
            throw new \UnexpectedValueException('the move object can not be empty.', -11964);
856
        }
857
858
        $dest_path =  $request->input('dest_path');
859
        if (!isset($dest_path))
860
        {
861
            throw new \UnexpectedValueException('the dest directory can not be empty.', -11965);
862
        }
863
864
        $document = DB::collection('wiki_' . $project_key)
865
            ->where('_id', $id)
866
            ->where('del_flag', '<>', 1)
867
            ->first();
868
        if (!$document)
869
        {
870
            throw new \UnexpectedValueException('the move object does not exist.', -11966);
871
        }
872
873 View Code Duplication
        if (isset($document['d']) && $document['d'] === 1)
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...
874
        {
875
            if (!$this->isPermissionAllowed($project_key, 'manage_project'))
876
            {
877
                return Response()->json(['ecode' => -10002, 'emsg' => 'permission denied.']);
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...
878
            }
879
        }
880
881
        $dest_directory = [];
882
        if ($dest_path !== '0')
883
        {
884
            $dest_directory = DB::collection('wiki_' . $project_key)
885
                ->where('_id', $dest_path)
886
                ->where('d', 1)
887
                ->where('del_flag', '<>', 1)
888
                ->first();
889
            if (!$dest_directory)
890
            {
891
                throw new \UnexpectedValueException('the dest directory does not exist.', -11967);
892
            }
893
        }
894
895
        $isExists = DB::collection('wiki_' . $project_key)
896
            ->where('parent', $dest_path)
897
            ->where('name', $document['name'])
898
            ->where('d', isset($document['d']) && $document['d'] === 1 ? '=' : '<>', 1)
899
            ->where('del_flag', '<>', 1)
900
            ->exists();
901
        if ($isExists)
902
        {
903
            throw new \UnexpectedValueException('the name cannot be repeated.', -11953);
904
        }
905
906
        $updValues = [];
907
        $updValues['parent'] = $dest_path;
908
        $updValues['pt'] = array_merge(isset($dest_directory['pt']) ? $dest_directory['pt'] : [], [$dest_path]);
909
        DB::collection('wiki_' . $project_key)->where('_id', $id)->update($updValues);
910
911 View Code Duplication
        if (isset($document['d']) && $document['d'] === 1)
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...
912
        {
913
            $subs = DB::collection('wiki_' . $project_key)
914
                ->where('pt', $id)
915
                ->where('del_flag', '<>', 1)
916
                ->get();
917
             foreach ($subs as $sub)
918
             {
919
                 $pt = isset($sub['pt']) ? $sub['pt'] : [];
920
                 $pind = array_search($id, $pt);
921
                 if ($pind !== false)
922
                 {
923
                     $tail = array_slice($pt, $pind);
924
                     $pt = array_merge($updValues['pt'], $tail);
925
                     DB::collection('wiki_' . $project_key)->where('_id', $sub['_id']->__toString())->update(['pt' => $pt]);
926
                 }
927
             }
928
        }
929
930
        $document = DB::collection('wiki_' . $project_key)->where('_id', $id)->first();
931
        return Response()->json(['ecode' => 0, 'data' => parent::arrange($document)]);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (arrange() instead of move()). Are you sure this is correct? If so, you might want to change this to $this->arrange().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
932
    }
933
934
    /**
935
     * Remove the specified resource from storage.
936
     *
937
     * @param  string  $project_key
938
     * @param  string  $id
939
     * @return \Illuminate\Http\Response
940
     */
941
    public function destroy($project_key, $id)
942
    {
943
        $document = DB::collection('wiki_' . $project_key)
944
            ->where('_id', $id)
945
            ->first();
946
        if (!$document)
947
        {
948
            throw new \UnexpectedValueException('the object does not exist.', -11954);
949
        }
950
951 View Code Duplication
        if (isset($document['d']) && $document['d'] === 1)
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...
952
        {
953
            if (!$this->isPermissionAllowed($project_key, 'manage_project'))
954
            {
955
                return Response()->json(['ecode' => -10002, 'emsg' => 'permission denied.']);
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...
956
            }
957
        }
958
959
        DB::collection('wiki_' . $project_key)->where('_id', $id)->update([ 'del_flag' => 1 ]);
960
961 View Code Duplication
        if (isset($document['d']) && $document['d'] === 1)
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...
962
        {
963
            DB::collection('wiki_' . $project_key)->whereRaw([ 'pt' => $id ])->update([ 'del_flag' => 1 ]);
964
        }
965
966
        $user = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
967
        Event::fire(new WikiEvent($project_key, $user, [ 'event_key' => 'delete_wiki', 'wiki_id' => $id ]));
968
969
        return Response()->json(['ecode' => 0, 'data' => [ 'id' => $id ]]);
970
    }
971
972
    /**
973
     * Upload file.
974
     *
975
     * @param  \Illuminate\Http\Request  $request
976
     * @param  String  $project_key
977
     * @param  String  $wid
978
     * @param  String  $fid
0 ignored issues
show
Bug introduced by
There is no parameter named $fid. 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...
979
     * @return \Illuminate\Http\Response
980
     */
981
    public function upload(Request $request, $project_key, $wid)
982
    {
983
        set_time_limit(0);
984
985
        if (!is_writable(config('filesystems.disks.local.root', '/tmp')))
986
        {
987
            throw new \UnexpectedValueException('the user has not the writable permission to the directory.', -15103);
988
        }
989
990
        $fields = array_keys($_FILES);
991
        $field = array_pop($fields);
992 View Code Duplication
        if (empty($_FILES) || $_FILES[$field]['error'] > 0)
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...
993
        {
994
            throw new \UnexpectedValueException('upload file errors.', -11959);
995
        }
996
997
        $document = DB::collection('wiki_' . $project_key)
998
            ->where('_id', $wid)
999
            ->where('del_flag', '<>', 1)
1000
            ->first();
1001
        if (!$document)
1002
        {
1003
            throw new \UnexpectedValueException('the object does not exist.', -11954);
1004
        }
1005
1006
        $basename = md5(microtime() . $_FILES[$field]['name']);
1007
        $sub_save_path = config('filesystems.disks.local.root', '/tmp') . '/' . substr($basename, 0, 2) . '/';
1008
        if (!is_dir($sub_save_path))
1009
        {
1010
            @mkdir($sub_save_path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1011
        }
1012
        move_uploaded_file($_FILES[$field]['tmp_name'], $sub_save_path . $basename);
1013
1014
        $data = [];
1015
1016
        $data['name'] = $_FILES[$field]['name'];;
1017
        $data['size']    = $_FILES[$field]['size'];
1018
        $data['type']    = $_FILES[$field]['type'];
1019
        $data['id'] = $data['index']   = $basename;
1020
1021
        $data['uploader'] = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
1022
        $data['uploaded_at'] = time();
1023
1024
        $attachments = [];
1025
        if (isset($document['attachments']) && $document['attachments'])
1026
        {
1027
            $attachments = $document['attachments'];
1028
        }
1029
1030
        $attachments[] = $data;
1031
        DB::collection('wiki_' . $project_key)->where('_id', $wid)->update([ 'attachments' => $attachments ]);
1032
1033
        return Response()->json(['ecode' => 0, 'data' => $data]);
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...
1034
    }
1035
1036
    /**
1037
     * remove file.
1038
     *
1039
     * @param  \Illuminate\Http\Request  $request
1040
     * @param  String  $project_key
1041
     * @param  String  $wid
1042
     * @return \Illuminate\Http\Response
1043
     */
1044
    public function remove(Request $request, $project_key, $wid, $fid)
1045
    {
1046
        $document = DB::collection('wiki_' . $project_key)
1047
            ->where('_id', $wid)
1048
            ->where('del_flag', '<>', 1)
1049
            ->first();
1050
        if (!$document)
1051
        {
1052
            throw new \UnexpectedValueException('the object does not exist.', -11954);
1053
        }
1054
1055 View Code Duplication
        if (!isset($document['attachments']) || !$document['attachments'])
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...
1056
        {
1057
            throw new \UnexpectedValueException('the file does not exist.', -11958);
1058
        }
1059
1060
        $new_attachments = [];
1061
        foreach ($document['attachments'] as $a)
1062
        {
1063
            if ($a['id'] !== $fid)
1064
            {
1065
                $new_attachments[] = $a;
1066
            }
1067
        }
1068
1069
        DB::collection('wiki_' . $project_key)->where('_id', $wid)->update([ 'attachments' => $new_attachments ]);
1070
        return Response()->json(['ecode' => 0, 'data' => [ 'id' => $fid ]]);
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...
1071
    }
1072
1073
    /**
1074
     * Download file or directory.
1075
     *
1076
     * @param  \Illuminate\Http\Request  $request
1077
     * @param  String  $project_key
1078
     * @param  String  $wid
1079
     * @return \Illuminate\Http\Response
1080
     */
1081
    public function download2(Request $request, $project_key, $wid)
1082
    {
1083
        set_time_limit(0);
1084
1085
        $document = DB::collection('wiki_' . $project_key)
1086
            ->where('_id', $wid)
1087
            ->where('del_flag', '<>', 1)
1088
            ->first();
1089
        if (!$document)
1090
        {
1091
            throw new \UnexpectedValueException('the object does not exist.', -11954);
1092
        }
1093
1094 View Code Duplication
        if (!isset($document['attachments']) || !$document['attachments'])
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...
1095
        {
1096
            throw new \UnexpectedValueException('the file does not exist.', -11958);
1097
        }
1098
1099
        $this->downloadFolder($document['name'], $document['attachments']);
1100
    }
1101
1102
    /**
1103
     * Download file or directory.
1104
     *
1105
     * @param  \Illuminate\Http\Request  $request
1106
     * @param  String  $project_key
1107
     * @param  String  $wid
1108
     * @param  String  $fid
1109
     * @return \Illuminate\Http\Response
1110
     */
1111
    public function download(Request $request, $project_key, $wid, $fid)
1112
    {
1113
        set_time_limit(0);
1114
1115
        $document = DB::collection('wiki_' . $project_key)
1116
            ->where('_id', $wid)
1117
            ->where('del_flag', '<>', 1)
1118
            ->first();
1119
        if (!$document)
1120
        {
1121
            throw new \UnexpectedValueException('the object does not exist.', -11954);
1122
        }
1123
1124 View Code Duplication
        if (!isset($document['attachments']) || !$document['attachments'])
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...
1125
        {
1126
            throw new \UnexpectedValueException('the file does not exist.', -11958);
1127
        }
1128
1129
        $isExists = false;
1130
        foreach ($document['attachments'] as $file)
1131
        {
1132
            if (isset($file['id']) && $file['id'] === $fid) 
1133
            {
1134
                $isExists = true;
1135
                break;
1136
            }
1137
        }
1138
1139
        if (!$isExists)
1140
        {
1141
            throw new \UnexpectedValueException('the file does not exist.', -11958);
1142
        }
1143
1144
        $this->downloadFile($file['name'], $file['index']);
0 ignored issues
show
Bug introduced by
The variable $file seems to be defined by a foreach iteration on line 1130. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
1145
    }
1146
1147
    /**
1148
     * Download file.
1149
     *
1150
     * @param  String  $name
1151
     * @param  array   $attachments
1152
     * @return \Illuminate\Http\Response
1153
     */
1154
    public function downloadFolder($name, $attachments)
1155
    {
1156
        setlocale(LC_ALL, 'zh_CN.UTF-8'); 
1157
1158
        $basepath = '/tmp/' . md5($this->user->id . microtime());
1159
        @mkdir($basepath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1160
1161
        $fullpath = $basepath . '/' . $name;
1162
        @mkdir($fullpath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1163
1164
        foreach ($attachments as $attachment)
1165
        {
1166
            $filepath = config('filesystems.disks.local.root', '/tmp') . '/' . substr($attachment['index'], 0, 2);
1167
            $filename = $filepath . '/' . $attachment['index'];
1168
            if (file_exists($filename))
1169
            {
1170
                @copy($filename, $fullpath . '/' . $attachment['name']);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1171
            }
1172
        }
1173
1174
        $fname = $basepath . '/' . $name . '.zip';
1175
        Zipper::make($fname)->folder($name)->add($basepath . '/' . $name);
1176
        Zipper::close();
1177
1178
        File::download($fname, $name . '.zip');
1179
1180
        exec('rm -rf ' . $basepath);
1181
    }
1182
1183
    /**
1184
     * Download file.
1185
     *
1186
     * @param  String  $name
1187
     * @param  String  $index
1188
     * @return \Illuminate\Http\Response
1189
     */
1190 View Code Duplication
    public function downloadFile($name, $index)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1191
    {
1192
        $filepath = config('filesystems.disks.local.root', '/tmp') . '/' . substr($index, 0, 2);
1193
        $filename = $filepath . '/' . $index;
1194
        if (!file_exists($filename))
1195
        {
1196
            throw new \UnexpectedValueException('file does not exist.', -11958);
1197
        }
1198
1199
        File::download($filename, $name);
1200
    }
1201
1202
    /**
1203
     * favorite action.
1204
     *
1205
     * @param  string  $project_key
1206
     * @param  string  $id
1207
     * @return \Illuminate\Http\Response
1208
     */
1209 View Code Duplication
    public function favorite(Request $request, $project_key, $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1210
    {
1211
        $document = DB::collection('wiki_' . $project_key)
1212
            ->where('_id', $id)
1213
            ->where('del_flag', '<>', 1)
1214
            ->first();
1215
        if (!$document)
1216
        {
1217
            throw new \UnexpectedValueException('the object does not exist.', -11954);
1218
        }
1219
1220
        WikiFavorites::where('wid', $id)->where('user.id', $this->user->id)->delete();
1221
1222
        $cur_user = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
1223
1224
        $flag = $request->input('flag');
1225
        if (isset($flag) && $flag)
1226
        {
1227
            WikiFavorites::create([ 'project_key' => $project_key, 'wid' => $id, 'user' => $cur_user ]);
1228
        }
1229
1230
        return Response()->json(['ecode' => 0, 'data' => ['id' => $id, 'user' => $cur_user, 'favorited' => $flag]]);
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...
1231
    }
1232
}
1233