Passed
Push — main ( cc6a11...9447d2 )
by Julian
04:07
created

UserController::littlelinkhome()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 15
rs 10
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Hash;
7
use Cohensive\OEmbed\Facades\OEmbed;
8
use Illuminate\Support\Facades\Schema;
9
use Illuminate\Support\Facades\Route;
10
use Illuminate\Support\Facades\Response;
11
use JeroenDesloovere\VCard\VCard;
12
use Illuminate\Validation\Rule;
13
use Illuminate\Support\Facades\Validator;
14
use Illuminate\Support\Facades\Mail;
15
use App\Mail\ReportSubmissionMail;
16
use GeoSot\EnvEditor\Facades\EnvEditor;
17
18
use Auth;
19
use DB;
20
use ZipArchive;
21
use File;
22
23
use App\Models\User;
24
use App\Models\Button;
25
use App\Models\Link;
26
use App\Models\LinkType;
27
use App\Models\UserData;
28
29
30
//Function tests if string starts with certain string (used to test for illegal strings)
31
function stringStartsWith($haystack, $needle, $case = true)
32
{
33
    if ($case) {
34
        return strpos($haystack, $needle, 0) === 0;
35
    }
36
    return stripos($haystack, $needle, 0) === 0;
37
}
38
39
//Function tests if string ends with certain string (used to test for illegal strings)
40
function stringEndsWith($haystack, $needle, $case = true)
41
{
42
    $expectedPosition = strlen($haystack) - strlen($needle);
43
    if ($case) {
44
        return strrpos($haystack, $needle, 0) === $expectedPosition;
45
    }
46
    return strripos($haystack, $needle, 0) === $expectedPosition;
47
}
48
49
class UserController extends Controller
50
{
51
52
    //Statistics of the number of clicks and links
53
    public function index()
54
    {
55
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
56
57
        $littlelink_name = Auth::user()->littlelink_name;
0 ignored issues
show
Bug introduced by
Accessing littlelink_name on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
58
        $userinfo = User::find($userId);
59
60
        $links = Link::where('user_id', $userId)->select('link')->count();
61
        $clicks = Link::where('user_id', $userId)->sum('click_number');
62
        $topLinks = Link::where('user_id', $userId)->orderby('click_number', 'desc')
63
            ->whereNotNull('link')->where('link', '<>', '')
64
            ->take(5)->get();
65
66
        $pageStats = [
67
            'visitors' => [
68
                'all' => visits('App\Models\User', $littlelink_name)->count(),
69
                'day' => visits('App\Models\User', $littlelink_name)->period('day')->count(),
70
                'week' => visits('App\Models\User', $littlelink_name)->period('week')->count(),
71
                'month' => visits('App\Models\User', $littlelink_name)->period('month')->count(),
72
                'year' => visits('App\Models\User', $littlelink_name)->period('year')->count(),
73
            ],
74
            'os' => visits('App\Models\User', $littlelink_name)->operatingSystems(),
75
            'referers' => visits('App\Models\User', $littlelink_name)->refs(),
76
            'countries' => visits('App\Models\User', $littlelink_name)->countries(),
77
        ];
78
79
80
81
        return view('studio/index', ['greeting' => $userinfo->name, 'toplinks' => $topLinks, 'links' => $links, 'clicks' => $clicks, 'pageStats' => $pageStats]);
82
    }
83
84
    //Show littlelink page. example => http://127.0.0.1:8000/+admin
85
    public function littlelink(request $request)
86
    {
87
        if(isset($request->useif)){
88
            $littlelink_name = User::select('littlelink_name')->where('id', $request->littlelink)->value('littlelink_name');
89
            $id = $request->littlelink;
90
        } else {
91
            $littlelink_name = $request->littlelink;
92
            $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
93
        }
94
95
        if (empty($id)) {
96
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
97
        }
98
     
99
        $userinfo = User::select('id', 'name', 'littlelink_name', 'littlelink_description', 'theme', 'role', 'block')->where('id', $id)->first();
100
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
101
        
102
        if ($userinfo->block == 'yes') {
0 ignored issues
show
Bug introduced by
The property block does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
Bug introduced by
The property block does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
103
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
104
        }
105
        
106
        $links = DB::table('links')->join('buttons', 'buttons.id', '=', 'links.button_id')->select('links.link', 'links.id', 'links.button_id', 'links.title', 'links.custom_css', 'links.custom_icon', 'buttons.name')->where('user_id', $id)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->get();
107
108
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
109
    }
110
111
    //Show littlelink page as home page if set in config
112
    public function littlelinkhome(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

112
    public function littlelinkhome(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
113
    {
114
        $littlelink_name = env('HOME_URL');
115
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
116
117
        if (empty($id)) {
118
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
119
        }
120
     
121
        $userinfo = User::select('id', 'name', 'littlelink_name', 'littlelink_description', 'theme', 'role', 'block')->where('id', $id)->first();
122
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
123
        
124
        $links = DB::table('links')->join('buttons', 'buttons.id', '=', 'links.button_id')->select('links.link', 'links.id', 'links.button_id', 'links.title', 'links.custom_css', 'links.custom_icon', 'buttons.name')->where('user_id', $id)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->get();
125
126
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
127
    }
128
129
    //Redirect to user page
130
    public function userRedirect(request $request)
131
    {
132
        $id = $request->id;
133
        $user = User::select('littlelink_name')->where('id', $id)->value('littlelink_name');
134
135
        if (empty($id)) {
136
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
137
        }
138
     
139
        if (empty($user)) {
140
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
141
        }
142
143
        return redirect(url('@'.$user));
144
    }
145
146
    //Show add/update form
147
    public function AddUpdateLink($id = 0)
148
    {
149
150
        if ($id !== 0) {
151
            $linkData = Link::find($id);
152
        } elseif ($id == 0) {
153
            $linkData = new Link(['typename' => 'link', 'id'=>'0']);
154
        } else {
155
            $linkData = new Link(['typename' => 'link', 'id'=>'0']);
156
        }
157
        $data['LinkTypes'] = LinkType::get();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
158
        $data['LinkData'] = $linkData;
159
        $data['LinkID'] = $id;
160
        $data['linkTypeID'] = "1";
161
        $data['title'] = "Predefined Site";
162
163
        if (Route::currentRouteName() != 'showButtons') {
164
            $links = DB::table('links')->where('id', $id)->first();
165
166
            $bid = $links->button_id;
167
168
            if($bid == 1 or $bid == 2){
169
                $data['linkTypeID'] = "2";
170
            } elseif ($bid == 42) {
171
                $data['linkTypeID'] = "3";
172
            } elseif ($bid == 43) {
173
                $data['linkTypeID'] = "4";
174
            } elseif ($bid == 93) {
175
                $data['linkTypeID'] = "5";
176
            } elseif ($bid == 6 or $bid == 7) {
177
                $data['linkTypeID'] = "6";
178
            } elseif ($bid == 44) {
179
                $data['linkTypeID'] = "7";
180
            } elseif ($bid == 96) {
181
                $data['linkTypeID'] = "8";
182
            } else {
183
                $data['linkTypeID'] = "1";
184
            }
185
186
            $data['title'] = LinkType::where('id', $data['linkTypeID'])->value('title');
187
        }
188
189
        foreach ($data['LinkTypes']->toArray() as $key => $val) {
190
            if ($val['typename'] === $linkData['typename']) {
191
                $data['SelectedLinkType'] = $val;
192
                break;
193
            }
194
        }
195
        
196
        return view('studio/edit-link', $data);
197
    }
198
199
    //Save add link
200
    public function saveLink(request $request)
201
    {
202
        $request->validate([
203
            'link' => 'sometimes|url',
204
        ]);
205
206
        $linkType = LinkType::find($request->linktype_id);
207
        $LinkTitle = ($request->link_text ?? $request->link_title) ?? $request->title;
208
        $LinkURL = $request->link_url ?? $request->link;
209
210
        $OrigLink = Link::find($request->linkid);
211
212
        $customParams = [];
213
        foreach ($request->all() as $key => $param) {
214
            //echo $key . " = " . $param . "<br />";
215
            if (str_starts_with($key, "_") ||  in_array($key, ['linktype_id', 'linktype_title', 'link_text', 'link_url']))
216
                continue;
217
218
            $customParams[$key] = $param;
219
        }
220
221
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
222
        $button = Button::where('name', $request->button)->first();
223
224
        if ($button && empty($LinkTitle))
225
            $LinkTitle = $button->alt;
226
227
        if ($linkType->typename == 'video' && empty($LinkTitle)) {
228
            $embed = OEmbed::get($LinkURL);
229
            if ($embed) {
230
                $LinkTitle = $embed->data()['title'];
231
            }
232
        }
233
234
        $message = (ucwords($button?->name) ?? ucwords($linkType->typename)). " has been ";
235
236
        if ($OrigLink) {
237
            //EDITING EXISTING
238
239
            $isCustomWebsite = $customParams['GetSiteIcon'] ?? null;
240
            $SpacerHeight = $customParams['height'] ?? null;
0 ignored issues
show
Unused Code introduced by
The assignment to $SpacerHeight is dead and can be removed.
Loading history...
241
242
                if($linkType->typename == "link" and $isCustomWebsite == "1"){
243
                    $OrigLink->update([
244
                        'link' => $LinkURL,
245
                        'title' => $LinkTitle,
246
                        'button_id' => "2",
247
                    ]);
248
                }elseif($linkType->typename == "link"){
249
                    $OrigLink->update([
250
                        'link' => $LinkURL,
251
                        'title' => $LinkTitle,
252
                        'button_id' => "1",
253
                    ]);
254
                }elseif($linkType->typename == "spacer"){
255
                    $OrigLink->update([
256
                        'link' => $LinkURL,
257
                        'title' => $customParams['height'] ?? null,
258
                        'button_id' => "43",
259
                    ]);
260
                }elseif($linkType->typename == "heading"){
261
                    $OrigLink->update([
262
                        'link' => $LinkURL,
263
                        'title' => $LinkTitle,
264
                        'button_id' => "42",
265
                    ]);
266
                }elseif($linkType->typename == "text"){
267
                    $sanitizedText = $request->text;
268
                    $sanitizedText = strip_tags($sanitizedText, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
269
                    $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
270
                    $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
271
                    $OrigLink->update([
272
                        'button_id' => "93",
273
                        'title' => $sanitizedText,
274
                    ]);
275
                }elseif($linkType->typename == "email"){
276
                    $LinkURL = "mailto:".$LinkURL;
277
                    $OrigLink->update([
278
                        'link' => $LinkURL,
279
                        'button_id' => $button?->id,
280
                        'title' => $LinkTitle,
281
                    ]);
282
                }elseif($linkType->typename == "telephone"){
283
                    $LinkURL = "tel:".$LinkURL;
284
                    $OrigLink->update([
285
                        'link' => $LinkURL,
286
                        'button_id' => $button?->id,
287
                        'title' => $LinkTitle,
288
                    ]);
289
                }elseif($linkType->typename == "vcard"){
290
291
                    $prefix = $request->input('prefix');
0 ignored issues
show
Unused Code introduced by
The assignment to $prefix is dead and can be removed.
Loading history...
292
                    $firstName = $request->input('first_name');
0 ignored issues
show
Unused Code introduced by
The assignment to $firstName is dead and can be removed.
Loading history...
293
                    $middleName = $request->input('middle_name');
0 ignored issues
show
Unused Code introduced by
The assignment to $middleName is dead and can be removed.
Loading history...
294
                    $lastName = $request->input('last_name');
0 ignored issues
show
Unused Code introduced by
The assignment to $lastName is dead and can be removed.
Loading history...
295
                    $suffix = $request->input('suffix');
0 ignored issues
show
Unused Code introduced by
The assignment to $suffix is dead and can be removed.
Loading history...
296
                    $nickname = $request->input('nickname');
0 ignored issues
show
Unused Code introduced by
The assignment to $nickname is dead and can be removed.
Loading history...
297
                    $organization = $request->input('organization');
0 ignored issues
show
Unused Code introduced by
The assignment to $organization is dead and can be removed.
Loading history...
298
                    $vtitle = $request->input('vtitle');
0 ignored issues
show
Unused Code introduced by
The assignment to $vtitle is dead and can be removed.
Loading history...
299
                    $role = $request->input('role');
0 ignored issues
show
Unused Code introduced by
The assignment to $role is dead and can be removed.
Loading history...
300
                    $workUrl = $request->input('work_url');
0 ignored issues
show
Unused Code introduced by
The assignment to $workUrl is dead and can be removed.
Loading history...
301
                    $email = $request->input('email');
0 ignored issues
show
Unused Code introduced by
The assignment to $email is dead and can be removed.
Loading history...
302
                    $workEmail = $request->input('work_email');
0 ignored issues
show
Unused Code introduced by
The assignment to $workEmail is dead and can be removed.
Loading history...
303
                    $homePhone = $request->input('home_phone');
0 ignored issues
show
Unused Code introduced by
The assignment to $homePhone is dead and can be removed.
Loading history...
304
                    $workPhone = $request->input('work_phone');
0 ignored issues
show
Unused Code introduced by
The assignment to $workPhone is dead and can be removed.
Loading history...
305
                    $cellPhone = $request->input('cell_phone');
0 ignored issues
show
Unused Code introduced by
The assignment to $cellPhone is dead and can be removed.
Loading history...
306
                    $homeAddressLabel = $request->input('home_address_label');
0 ignored issues
show
Unused Code introduced by
The assignment to $homeAddressLabel is dead and can be removed.
Loading history...
307
                    $homeAddressStreet = $request->input('home_address_street');
0 ignored issues
show
Unused Code introduced by
The assignment to $homeAddressStreet is dead and can be removed.
Loading history...
308
                    $homeAddressCity = $request->input('home_address_city');
0 ignored issues
show
Unused Code introduced by
The assignment to $homeAddressCity is dead and can be removed.
Loading history...
309
                    $homeAddressState = $request->input('home_address_state');
0 ignored issues
show
Unused Code introduced by
The assignment to $homeAddressState is dead and can be removed.
Loading history...
310
                    $homeAddressZip = $request->input('home_address_zip');
0 ignored issues
show
Unused Code introduced by
The assignment to $homeAddressZip is dead and can be removed.
Loading history...
311
                    $homeAddressCountry = $request->input('home_address_country');
0 ignored issues
show
Unused Code introduced by
The assignment to $homeAddressCountry is dead and can be removed.
Loading history...
312
                    $workAddressLabel = $request->input('work_address_label');
0 ignored issues
show
Unused Code introduced by
The assignment to $workAddressLabel is dead and can be removed.
Loading history...
313
                    $workAddressStreet = $request->input('work_address_street');
0 ignored issues
show
Unused Code introduced by
The assignment to $workAddressStreet is dead and can be removed.
Loading history...
314
                    $workAddressCity = $request->input('work_address_city');
0 ignored issues
show
Unused Code introduced by
The assignment to $workAddressCity is dead and can be removed.
Loading history...
315
                    $workAddressState = $request->input('work_address_state');
0 ignored issues
show
Unused Code introduced by
The assignment to $workAddressState is dead and can be removed.
Loading history...
316
                    $workAddressZip = $request->input('work_address_zip');
0 ignored issues
show
Unused Code introduced by
The assignment to $workAddressZip is dead and can be removed.
Loading history...
317
                    $workAddressCountry = $request->input('work_address_country');
0 ignored issues
show
Unused Code introduced by
The assignment to $workAddressCountry is dead and can be removed.
Loading history...
318
    
319
                    // Create an array with all the input fields
320
                    $data = [
321
                        'prefix' => $request->input('prefix'),
322
                        'first_name' => $request->input('first_name'),
323
                        'middle_name' => $request->input('middle_name'),
324
                        'last_name' => $request->input('last_name'),
325
                        'suffix' => $request->input('suffix'),
326
                        'nickname' => $request->input('nickname'),
327
                        'organization' => $request->input('organization'),
328
                        'vtitle' => $request->input('vtitle'),
329
                        'role' => $request->input('role'),
330
                        'work_url' => $request->input('work_url'),
331
                        'email' => $request->input('email'),
332
                        'work_email' => $request->input('work_email'),
333
                        'home_phone' => $request->input('home_phone'),
334
                        'work_phone' => $request->input('work_phone'),
335
                        'cell_phone' => $request->input('cell_phone'),
336
                        'home_address_label' => $request->input('home_address_label'),
337
                        'home_address_street' => $request->input('home_address_street'),
338
                        'home_address_city' => $request->input('home_address_city'),
339
                        'home_address_state' => $request->input('home_address_state'),
340
                        'home_address_zip' => $request->input('home_address_zip'),
341
                        'home_address_country' => $request->input('home_address_country'),
342
                        'work_address_label' => $request->input('work_address_label'),
343
                        'work_address_street' => $request->input('work_address_street'),
344
                        'work_address_city' => $request->input('work_address_city'),
345
                        'work_address_state' => $request->input('work_address_state'),
346
                        'work_address_zip' => $request->input('work_address_zip'),
347
                        'work_address_country' => $request->input('work_address_country'),
348
                    ];
349
                    
350
                    // Convert the array to JSON format
351
                    $json = json_encode($data);
352
                    
353
                    // Set the JSON as the variable $links->link, or null if the JSON is empty
354
                    $LinkURL = $json ? $json : null;        
355
356
                    $OrigLink->update([
357
                        'link' => $LinkURL,
358
                        'button_id' => 96,
359
                        'title' => $LinkTitle,
360
                    ]);
361
                }else{
362
                    $OrigLink->update([
363
                        'link' => $LinkURL,
364
                        'title' => $LinkTitle,
365
                        'button_id' => $button?->id,
366
                    ]);
367
                }
368
                
369
            $message .="updated";
370
371
        } else {
372
            // ADDING NEW
373
374
            $isCustomWebsite = $customParams['GetSiteIcon'] ?? null;
375
            $SpacerHeight = $customParams['height'] ?? null;
376
            
377
            $links = new Link;
378
            $links->link = $LinkURL;
379
            $links->user_id = $userId;
380
            if($linkType->typename == "spacer"){
381
            $links->title = $SpacerHeight;
382
            }else{
383
            $links->title = $LinkTitle;
384
            }
385
            if($linkType->typename == "link" and $isCustomWebsite == "1"){
386
                $links->button_id = "2";
387
            }elseif($linkType->typename == "link"){
388
                $links->button_id = "1";
389
            }elseif($linkType->typename == "spacer"){
390
                $links->button_id = "43";
391
            }elseif($linkType->typename == "heading"){
392
                $links->button_id = "42";
393
            }elseif($linkType->typename == "text"){
394
                $sanitizedText = $request->text;
395
                $sanitizedText = strip_tags($sanitizedText, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
396
                $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
397
                $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
398
                $links->button_id = "93";
399
                $links->title = $sanitizedText;
400
            }elseif($linkType->typename == "email"){
401
                $links->link = "mailto:".$links->link;
402
                $links->button_id = $button?->id;
403
            }elseif($linkType->typename == "telephone"){
404
                $links->link = "tel:".$links->link;
405
                $links->button_id = $button?->id;
406
            }elseif($linkType->typename == "vcard"){
407
408
                $prefix = $request->input('prefix');
409
                $firstName = $request->input('first_name');
410
                $middleName = $request->input('middle_name');
411
                $lastName = $request->input('last_name');
412
                $suffix = $request->input('suffix');
413
                $nickname = $request->input('nickname');
414
                $organization = $request->input('organization');
415
                $vtitle = $request->input('vtitle');
416
                $role = $request->input('role');
417
                $workUrl = $request->input('work_url');
418
                $email = $request->input('email');
419
                $workEmail = $request->input('work_email');
420
                $homePhone = $request->input('home_phone');
421
                $workPhone = $request->input('work_phone');
422
                $cellPhone = $request->input('cell_phone');
423
                $homeAddressLabel = $request->input('home_address_label');
424
                $homeAddressStreet = $request->input('home_address_street');
425
                $homeAddressCity = $request->input('home_address_city');
426
                $homeAddressState = $request->input('home_address_state');
427
                $homeAddressZip = $request->input('home_address_zip');
428
                $homeAddressCountry = $request->input('home_address_country');
429
                $workAddressLabel = $request->input('work_address_label');
430
                $workAddressStreet = $request->input('work_address_street');
431
                $workAddressCity = $request->input('work_address_city');
432
                $workAddressState = $request->input('work_address_state');
433
                $workAddressZip = $request->input('work_address_zip');
434
                $workAddressCountry = $request->input('work_address_country');
435
436
                // Create an array with all the input fields
437
                $data = [
438
                    'prefix' => $request->input('prefix'),
439
                    'first_name' => $request->input('first_name'),
440
                    'middle_name' => $request->input('middle_name'),
441
                    'last_name' => $request->input('last_name'),
442
                    'suffix' => $request->input('suffix'),
443
                    'nickname' => $request->input('nickname'),
444
                    'organization' => $request->input('organization'),
445
                    'vtitle' => $request->input('vtitle'),
446
                    'role' => $request->input('role'),
447
                    'work_url' => $request->input('work_url'),
448
                    'email' => $request->input('email'),
449
                    'work_email' => $request->input('work_email'),
450
                    'home_phone' => $request->input('home_phone'),
451
                    'work_phone' => $request->input('work_phone'),
452
                    'cell_phone' => $request->input('cell_phone'),
453
                    'home_address_label' => $request->input('home_address_label'),
454
                    'home_address_street' => $request->input('home_address_street'),
455
                    'home_address_city' => $request->input('home_address_city'),
456
                    'home_address_state' => $request->input('home_address_state'),
457
                    'home_address_zip' => $request->input('home_address_zip'),
458
                    'home_address_country' => $request->input('home_address_country'),
459
                    'work_address_label' => $request->input('work_address_label'),
460
                    'work_address_street' => $request->input('work_address_street'),
461
                    'work_address_city' => $request->input('work_address_city'),
462
                    'work_address_state' => $request->input('work_address_state'),
463
                    'work_address_zip' => $request->input('work_address_zip'),
464
                    'work_address_country' => $request->input('work_address_country'),
465
                ];
466
                
467
                // Convert the array to JSON format
468
                $json = json_encode($data);
469
                
470
                // Set the JSON as the variable $links->link, or null if the JSON is empty
471
                $links->link = $json ? $json : null;               
472
473
                $links->button_id = 96;
474
            }else{
475
                $links->button_id = $button?->id;
476
            }
477
478
            if(empty($links->button_id)) {
479
                return redirect(route('showButtons')); die;
0 ignored issues
show
Unused Code introduced by
ExitNode is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
480
            }
481
            
482
            $links->save();
483
484
            $links->order = ($links->id - 1);
485
            $links->save();
486
            $message .= "added";
487
        }
488
489
            if ($request->input('param') == 'add_more') {
490
                return Redirect('studio/add-link')
491
                ->with('success', $message);
492
            } else {
493
                return Redirect('studio/links')
494
                ->with('success', $message);
495
            }
496
497
    }
498
499
    public function sortLinks(Request $request)
500
    {
501
        $linkOrders  = $request->input("linkOrders", []);
502
        $currentPage = $request->input("currentPage", 1);
503
        $perPage     = $request->input("perPage", 0);
504
505
        if ($perPage == 0) {
506
            $currentPage = 1;
507
        }
508
509
        $linkOrders = array_unique(array_filter($linkOrders));
510
        if (!$linkOrders || $currentPage < 1) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $linkOrders 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...
511
            return response()->json([
512
                'status' => 'ERROR',
513
            ]);
514
        }
515
516
        $newOrder = $perPage * ($currentPage - 1);
517
        $linkNewOrders = [];
518
        foreach ($linkOrders as $linkId) {
519
            if ($linkId < 0) {
520
                continue;
521
            }
522
523
            $linkNewOrders[$linkId] = $newOrder;
524
            Link::where("id", $linkId)
525
                ->update([
526
                    'order' => $newOrder
527
                ]);
528
            $newOrder++;
529
        }
530
531
        return response()->json([
532
            'status' => 'OK',
533
            'linkOrders' => $linkNewOrders,
534
        ]);
535
    }
536
537
538
    //Count the number of clicks and redirect to link
539
    public function clickNumber(request $request)
540
    {
541
        $linkId = $request->id;
542
543
        if (substr($linkId, -1) == '+') {
544
            $linkWithoutPlus = str_replace('+', '', $linkId);
545
            return redirect(url('info/'.$linkWithoutPlus));
546
        }
547
    
548
        $link = Link::find($linkId);
549
550
        if (empty($link)) {
551
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
552
        }
553
554
        $link = $link->link;
555
556
        if (empty($linkId)) {
557
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
558
        }
559
560
        Link::where('id', $linkId)->increment('click_number', 1);
561
562
        $response = redirect()->away($link);
563
        $response->header('X-Robots-Tag', 'noindex, nofollow');
564
565
        return $response;
566
    }
567
568
    //Download Vcard
569
    public function vcard(request $request)
570
    {
571
        $linkId = $request->id;
572
573
        // Find the link with the specified ID
574
        $link = Link::findOrFail($linkId);
575
576
        $json = $link->link;
577
578
        // Decode the JSON to a PHP array
579
        $data = json_decode($json, true);
580
        
581
        // Create a new vCard object
582
        $vcard = new VCard();
583
        
584
        // Set the vCard properties from the $data array
585
        $vcard->addName($data['last_name'], $data['first_name'], $data['middle_name'], $data['prefix'], $data['suffix']);
586
        $vcard->addCompany($data['organization']);
587
        $vcard->addJobtitle($data['vtitle']);
588
        $vcard->addRole($data['role']);
589
        $vcard->addEmail($data['email']);
590
        $vcard->addEmail($data['work_email'], 'WORK');
591
        $vcard->addURL($data['work_url'], 'WORK');
592
        $vcard->addPhoneNumber($data['home_phone'], 'HOME');
593
        $vcard->addPhoneNumber($data['work_phone'], 'WORK');
594
        $vcard->addPhoneNumber($data['cell_phone'], 'CELL');
595
        $vcard->addAddress($data['home_address_street'], '', $data['home_address_city'], $data['home_address_state'], $data['home_address_zip'], $data['home_address_country'], 'HOME');
596
        $vcard->addAddress($data['work_address_street'], '', $data['work_address_city'], $data['work_address_state'], $data['work_address_zip'], $data['work_address_country'], 'WORK');
597
        
598
599
        // $vcard->addPhoto(base_path('img/1.png'));
600
        
601
        // Generate the vCard file contents
602
        $file_contents = $vcard->getOutput();
603
        
604
        // Set the file headers for download
605
        $headers = [
606
            'Content-Type' => 'text/x-vcard',
607
            'Content-Disposition' => 'attachment; filename="contact.vcf"'
608
        ];
609
        
610
        Link::where('id', $linkId)->increment('click_number', 1);
611
612
        // Return the file download response
613
        return response()->make($file_contents, 200, $headers);
614
615
    }
616
617
    //Show link, click number, up link in links page
618
    public function showLinks()
619
    {
620
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
621
        $data['pagePage'] = 10;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
622
        
623
        $data['links'] = Link::select('id', 'link', 'title', 'order', 'click_number', 'up_link', 'links.button_id')->where('user_id', $userId)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->paginate(99999);
624
        return view('studio/links', $data);
625
    }
626
627
    //Delete link
628
    public function deleteLink(request $request)
629
    {
630
        $linkId = $request->id;
631
632
        Link::where('id', $linkId)->delete();
633
634
        $directory = base_path("assets/favicon/icons");
635
        $files = scandir($directory);
636
        foreach($files as $file) {
637
        if (strpos($file, $linkId.".") !== false) {
638
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
639
        if (isset($pathinfo)) {
640
        try{File::delete(base_path("assets/favicon/icons")."/".$linkId.".".$pathinfo);} catch (exception $e) {}
0 ignored issues
show
Bug introduced by
The type App\Http\Controllers\exception was not found. Did you mean exception? If so, make sure to prefix the type with \.
Loading history...
introduced by
Consider moving this CATCH statement to a new line.
Loading history...
641
        }
642
643
        return redirect('/studio/links');
644
    }
645
646
    //Delete icon
647
    public function clearIcon(request $request)
648
    {
649
        $linkId = $request->id;
650
651
        $directory = base_path("assets/favicon/icons");
652
        $files = scandir($directory);
653
        foreach($files as $file) {
654
        if (strpos($file, $linkId.".") !== false) {
655
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
656
        if (isset($pathinfo)) {
657
        try{File::delete(base_path("assets/favicon/icons")."/".$linkId.".".$pathinfo);} catch (exception $e) {}
0 ignored issues
show
introduced by
Consider moving this CATCH statement to a new line.
Loading history...
658
        }
659
660
        return redirect('/studio/links');
661
    }
662
663
    //Raise link on the littlelink page
664
    public function upLink(request $request)
665
    {
666
        $linkId = $request->id;
667
        $upLink = $request->up;
668
669
        if ($upLink == 'yes') {
670
            $up = 'no';
671
        } elseif ($upLink == 'no') {
672
            $up = 'yes';
673
        }
674
675
        Link::where('id', $linkId)->update(['up_link' => $up]);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $up does not seem to be defined for all execution paths leading up to this point.
Loading history...
676
677
        return back();
678
    }
679
680
    //Show link to edit
681
    public function showLink(request $request)
682
    {
683
        $linkId = $request->id;
684
685
        $link = Link::where('id', $linkId)->value('link');
686
        $title = Link::where('id', $linkId)->value('title');
687
        $order = Link::where('id', $linkId)->value('order');
688
        $custom_css = Link::where('id', $linkId)->value('custom_css');
689
        $buttonId = Link::where('id', $linkId)->value('button_id');
690
        $buttonName = Button::where('id', $buttonId)->value('name');
691
692
        $buttons = Button::select('id', 'name')->orderBy('name', 'asc')->get();
693
694
        return view('studio/edit-link', ['custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId, 'buttonName' => $buttonName]);
695
    }
696
697
    //Show custom CSS + custom icon
698
    public function showCSS(request $request)
699
    {
700
        $linkId = $request->id;
701
702
        $link = Link::where('id', $linkId)->value('link');
703
        $title = Link::where('id', $linkId)->value('title');
704
        $order = Link::where('id', $linkId)->value('order');
705
        $custom_css = Link::where('id', $linkId)->value('custom_css');
706
        $custom_icon = Link::where('id', $linkId)->value('custom_icon');
707
        $buttonId = Link::where('id', $linkId)->value('button_id');
708
709
        $buttons = Button::select('id', 'name')->get();
710
711
        return view('studio/button-editor', ['custom_icon' => $custom_icon, 'custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId]);
712
    }
713
714
    //Save edit link
715
    public function editLink(request $request)
716
    {
717
        $request->validate([
718
            'link' => 'required|url',
719
            'title' => 'required',
720
            'button' => 'required',
721
        ]);
722
723
        if (stringStartsWith($request->link, 'http://') == 'true' or stringStartsWith($request->link, 'https://') == 'true' or stringStartsWith($request->link, 'mailto:') == 'true')
724
            $link1 = $request->link;
725
        else
726
            $link1 = 'https://' . $request->link;
727
        if (stringEndsWith($request->link, '/') == 'true')
728
            $link = rtrim($link1, "/ ");
729
        else
730
        $link = $link1;
731
        $title = $request->title;
732
        $order = $request->order;
733
        $button = $request->button;
734
        $linkId = $request->id;
735
736
        $buttonId = Button::select('id')->where('name', $button)->value('id');
737
738
        Link::where('id', $linkId)->update(['link' => $link, 'title' => $title, 'order' => $order, 'button_id' => $buttonId]);
739
740
        return redirect('/studio/links');
741
    }
742
743
    //Save edit custom CSS + custom icon
744
    public function editCSS(request $request)
745
    {
746
        $linkId = $request->id;
747
        $custom_icon = $request->custom_icon;
748
        $custom_css = $request->custom_css;
749
750
        if ($request->custom_css == "" and $request->custom_icon = !"") {
0 ignored issues
show
Bug introduced by
The property custom_icon does not seem to exist on Illuminate\Http\Request.
Loading history...
751
            Link::where('id', $linkId)->update(['custom_icon' => $custom_icon]);
752
        } elseif ($request->custom_icon == "" and $request->custom_css = !"") {
0 ignored issues
show
Bug introduced by
The property custom_css does not seem to exist on Illuminate\Http\Request.
Loading history...
753
            Link::where('id', $linkId)->update(['custom_css' => $custom_css]);
754
        } else {
755
            Link::where('id', $linkId)->update([]);
756
        }
757
        return Redirect('#result');
758
    }
759
760
    //Show littlelinke page for edit
761
    public function showPage(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

761
    public function showPage(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
762
    {
763
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
764
765
        $data['pages'] = User::where('id', $userId)->select('littlelink_name', 'littlelink_description', 'image', 'name')->get();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
766
767
        return view('/studio/page', $data);
768
    }
769
770
    //Save littlelink page (name, description, logo)
771
    public function editPage(Request $request)
772
    {
773
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
774
        $littlelink_name = Auth::user()->littlelink_name;
0 ignored issues
show
Bug introduced by
Accessing littlelink_name on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
775
    
776
        $validator = Validator::make($request->all(), [
777
            'littlelink_name' => [
778
                'sometimes',
779
                'max:255',
780
                'string',
781
                'isunique:users,id,'.$userId,
782
            ],
783
            'name' => 'sometimes|max:255|string',
784
            'image' => 'sometimes|image|mimes:jpeg,jpg,png,webp|max:2048', // Max file size: 2MB
785
        ], [
786
            'littlelink_name.unique' => __('messages.That handle has already been taken'),
787
            'image.image' => __('messages.The selected file must be an image'),
788
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP.',
789
            'image.max' => __('messages.The image size should not exceed 2MB'),
790
        ]);
791
    
792
        if ($validator->fails()) {
793
            return redirect('/studio/page')->withErrors($validator)->withInput();
794
        }
795
    
796
        $profilePhoto = $request->file('image');
797
        $pageName = $request->littlelink_name;
798
        $pageDescription = strip_tags($request->pageDescription, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
799
        $pageDescription = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $pageDescription);
800
        $pageDescription = strip_tags_except_allowed_protocols($pageDescription);
801
        $name = $request->name;
802
        $checkmark = $request->checkmark;
803
        $sharebtn = $request->sharebtn;
804
        $tablinks = $request->tablinks;
805
806
        if(env('HOME_URL') !== '' && $pageName != $littlelink_name && $littlelink_name == env('HOME_URL')){
807
            EnvEditor::editKey('HOME_URL', $pageName);
808
        }
809
    
810
        User::where('id', $userId)->update([
811
            'littlelink_name' => $pageName,
812
            'littlelink_description' => $pageDescription,
813
            'name' => $name
814
        ]);
815
    
816
        if ($request->hasFile('image')) {
817
            $fileName = $userId . '_' . time() . "." . $profilePhoto->extension();
818
            $profilePhoto->move(base_path('assets/img'), $fileName);
819
        }
820
    
821
        if ($checkmark == "on") {
822
            UserData::saveData($userId, 'checkmark', true);
823
        } else {
824
            UserData::saveData($userId, 'checkmark', false);
825
        }
826
    
827
        if ($sharebtn == "on") {
828
            UserData::saveData($userId, 'disable-sharebtn', false);
829
        } else {
830
            UserData::saveData($userId, 'disable-sharebtn', true);
831
        }
832
833
        if ($tablinks == "on") {
834
            UserData::saveData($userId, 'links-new-tab', true);
835
        } else {
836
            UserData::saveData($userId, 'links-new-tab', false);
837
        }
838
    
839
        return Redirect('/studio/page');
840
    }
841
842
    //Upload custom theme background image
843
    public function themeBackground(Request $request)
844
    {
845
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
846
        $littlelink_name = Auth::user()->littlelink_name;
0 ignored issues
show
Bug introduced by
Accessing littlelink_name on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
Unused Code introduced by
The assignment to $littlelink_name is dead and can be removed.
Loading history...
847
    
848
        $request->validate([
849
            'image' => 'required|image|mimes:jpeg,jpg,png,webp,gif|max:2048', // Max file size: 2MB
850
        ], [
851
            'image.required' => __('messages.Please select an image'),
852
            'image.image' => __('messages.The selected file must be an image'),
853
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP, GIF.',
854
            'image.max' => __('messages.The image size should not exceed 2MB'),
855
        ]);
856
    
857
        $customBackground = $request->file('image');
858
    
859
        if ($customBackground) {
860
            $directory = base_path('assets/img/background-img/');
861
            $files = scandir($directory);
862
            $pathinfo = "error.error";
863
            foreach ($files as $file) {
864
                if (strpos($file, $userId . '.') !== false) {
865
                    $pathinfo = $userId . "." . pathinfo($file, PATHINFO_EXTENSION);
0 ignored issues
show
Bug introduced by
Are you sure pathinfo($file, App\Http...ers\PATHINFO_EXTENSION) of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

865
                    $pathinfo = $userId . "." . /** @scrutinizer ignore-type */ pathinfo($file, PATHINFO_EXTENSION);
Loading history...
866
                }
867
            }
868
    
869
            if (file_exists(base_path('assets/img/background-img/') . $pathinfo)) {
870
                File::delete(base_path('assets/img/background-img/') . $pathinfo);
871
            }
872
    
873
            $fileName = $userId . '_' . time() . "." . $customBackground->extension();
874
            $customBackground->move(base_path('assets/img/background-img/'), $fileName);
875
    
876
            if (extension_loaded('imagick')) {
877
                $imagePath = base_path('assets/img/background-img/') . $fileName;
878
                $image = new \Imagick($imagePath);
879
                $image->stripImage();
880
                $image->writeImage($imagePath);
881
            }
882
    
883
            return redirect('/studio/theme');
884
        }
885
    
886
        return redirect('/studio/theme')->with('error', 'Please select a valid image file.');
887
    }
888
889
    //Delete custom background image
890
    public function removeBackground()
891
    {
892
893
        $user_id = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
894
        $path = findBackground($user_id);
895
        $path = base_path('assets/img/background-img/'.$path);
896
        
897
        if (File::exists($path)) {
898
            File::delete($path);
899
        }
900
901
        return back();
902
    }
903
904
905
    //Show custom theme
906
    public function showTheme(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

906
    public function showTheme(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
907
    {
908
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
909
910
        $data['pages'] = User::where('id', $userId)->select('littlelink_name', 'theme')->get();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
911
912
        return view('/studio/theme', $data);
913
    }
914
915
    //Save custom theme
916
    public function editTheme(request $request)
917
    {
918
        $request->validate([
919
            'zip' => 'sometimes|mimes:zip',
920
        ]);
921
922
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
923
924
        $zipfile = $request->file('zip');
925
926
        $theme = $request->theme;
927
        $message = "";
928
929
        User::where('id', $userId)->update(['theme' => $theme]);
930
931
932
933
        if (!empty($zipfile)) {
934
935
            $zipfile->move(base_path('/themes'), "temp.zip");
936
937
            $zip = new ZipArchive;
938
            $zip->open(base_path() . '/themes/temp.zip');
939
            $zip->extractTo(base_path() . '/themes');
940
            $zip->close();
941
            unlink(base_path() . '/themes/temp.zip');
942
943
            // Removes version numbers from folder.
944
945
            $folder = base_path('themes');
946
            $regex = '/[0-9.-]/';
947
            $files = scandir($folder);
948
949
            foreach ($files as $file) {
950
                if ($file !== '.' && $file !== '..') {
951
                    if (preg_match($regex, $file)) {
952
                        $new_file = preg_replace($regex, '', $file);
953
                        File::copyDirectory($folder . '/' . $file, $folder . '/' . $new_file);
954
                        $dirname = $folder . '/' . $file;
955
                        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
956
                            system('rmdir ' . escapeshellarg($dirname) . ' /s /q');
957
                        } else {
958
                            system("rm -rf " . escapeshellarg($dirname));
959
                        }
960
                    }
961
                }
962
            }
963
        }
964
965
966
        return Redirect('/studio/theme')->with("success", $message);
967
    }
968
969
    //Show user (name, email, password)
970
    public function showProfile(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

970
    public function showProfile(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
971
    {
972
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
973
974
        $data['profile'] = User::where('id', $userId)->select('name', 'email', 'role')->get();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
975
976
        return view('/studio/profile', $data);
977
    }
978
979
    //Save user (name, email, password)
980
    public function editProfile(request $request)
981
    {
982
        $request->validate([
983
            'name' => 'sometimes|required|unique:users',
984
            'email' => 'sometimes|required|email|unique:users',
985
            'password' => 'sometimes|min:8',
986
        ]);
987
988
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
989
990
        $name = $request->name;
991
        $email = $request->email;
992
        $password = Hash::make($request->password);
993
994
        if ($request->name != '') {
995
            User::where('id', $userId)->update(['name' => $name]);
996
        } elseif ($request->email != '') {
997
            User::where('id', $userId)->update(['email' => $email]);
998
        } elseif ($request->password != '') {
999
            User::where('id', $userId)->update(['password' => $password]);
1000
            Auth::logout();
1001
        }
1002
        return back();
1003
    }
1004
1005
    //Show user theme credit page
1006
    public function theme(request $request)
1007
    {
1008
        $littlelink_name = $request->littlelink;
1009
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
1010
1011
        if (empty($id)) {
1012
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1013
        }
1014
1015
        $userinfo = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->first();
1016
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
1017
1018
        $links = DB::table('links')->join('buttons', 'buttons.id', '=', 'links.button_id')->select('links.link', 'links.id', 'links.button_id', 'links.title', 'links.custom_css', 'links.custom_icon', 'buttons.name')->where('user_id', $id)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->get();
1019
1020
        return view('components/theme', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
1021
    }
1022
1023
    //Delete existing user
1024
    public function deleteUser(request $request)
1025
    {
1026
1027
        // echo $request->id;
1028
        // echo "<br>";
1029
        // echo Auth::id();
1030
        $id = $request->id;
1031
1032
    if($id == Auth::id() and $id != "1") {
1033
1034
        Link::where('user_id', $id)->delete();
1035
1036
        $user = User::find($id);
1037
1038
        Schema::disableForeignKeyConstraints();
1039
        $user->forceDelete();
1040
        Schema::enableForeignKeyConstraints();
1041
    }
1042
1043
        return redirect('/');
1044
    }
1045
1046
    //Delete profile picture
1047
    public function delProfilePicture()
1048
    {
1049
        $user_id = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
1050
        $path = base_path(findAvatar($user_id));
1051
        
1052
        if (File::exists($path)) {
1053
            File::delete($path);
1054
        }
1055
1056
        return back();
1057
    }
1058
1059
    //Export user links
1060
    public function exportLinks(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1060
    public function exportLinks(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1061
    {
1062
        $userId = Auth::id();
1063
        $user = User::find($userId);
1064
        $links = Link::where('user_id', $userId)->get();
1065
        
1066
        if (!$user) {
1067
            // handle the case where the user is null
1068
            return response()->json(['message' => 'User not found'], 404);
1069
        }
1070
1071
        $userData['links'] = $links->toArray();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$userData was never initialized. Although not strictly required by PHP, it is generally a good practice to add $userData = array(); before regardless.
Loading history...
1072
1073
        $domain = $_SERVER['HTTP_HOST'];
1074
        $date = date('Y-m-d_H-i-s');
1075
        $fileName = "links-$domain-$date.json";
1076
        $headers = [
1077
            'Content-Type' => 'application/json',
1078
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
1079
        ];
1080
        return response()->json($userData, 200, $headers);
1081
1082
        return back();
0 ignored issues
show
Unused Code introduced by
return back() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1083
    }
1084
1085
    //Export all user data
1086
    public function exportAll(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1086
    public function exportAll(/** @scrutinizer ignore-unused */ Request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1087
    {
1088
        $userId = Auth::id();
1089
        $user = User::find($userId);
1090
        $links = Link::where('user_id', $userId)->get();
1091
    
1092
        if (!$user) {
1093
            // handle the case where the user is null
1094
            return response()->json(['message' => 'User not found'], 404);
1095
        }
1096
    
1097
        $userData = $user->toArray();
1098
        $userData['links'] = $links->toArray();
1099
    
1100
        function findAvatar($name){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1101
            $directory = base_path('assets/img');
1102
            $files = scandir($directory);
1103
            $pathinfo = "error.error";
1104
            foreach($files as $file) {
1105
            if (strpos($file, $name.'.') !== false) {
1106
            $pathinfo = "/img/" . $name. "." . pathinfo($file, PATHINFO_EXTENSION);
0 ignored issues
show
Bug introduced by
Are you sure pathinfo($file, App\Http...ers\PATHINFO_EXTENSION) of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1106
            $pathinfo = "/img/" . $name. "." . /** @scrutinizer ignore-type */ pathinfo($file, PATHINFO_EXTENSION);
Loading history...
1107
            }}
1108
            return $pathinfo;
1109
          }
1110
1111
        if (file_exists(base_path(findAvatar($userId)))){
1112
            $imagePath = base_path(findAvatar($userId));
1113
            $imageData = base64_encode(file_get_contents($imagePath));
1114
            $userData['image_data'] = $imageData;
1115
    
1116
            $imageExtension = pathinfo($imagePath, PATHINFO_EXTENSION);
1117
            $userData['image_extension'] = $imageExtension;
1118
        }
1119
    
1120
        $domain = $_SERVER['HTTP_HOST'];
1121
        $date = date('Y-m-d_H-i-s');
1122
        $fileName = "user_data-$domain-$date.json";
1123
        $headers = [
1124
            'Content-Type' => 'application/json',
1125
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
1126
        ];
1127
        return response()->json($userData, 200, $headers);
1128
    
1129
        return back();
0 ignored issues
show
Unused Code introduced by
return back() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1130
    }    
1131
1132
    public function importData(Request $request)
1133
    {
1134
        try {
1135
            // Get the JSON data from the uploaded file
1136
            if (!$request->hasFile('import') || !$request->file('import')->isValid()) {
1137
                throw new \Exception('File not uploaded or is faulty');
1138
            }
1139
            $file = $request->file('import');
1140
            $jsonString = $file->get();
1141
            $userData = json_decode($jsonString, true);
1142
    
1143
            // Update the authenticated user's profile data if defined in the JSON file
1144
            $user = auth()->user();
1145
            if (isset($userData['name'])) {
1146
                $user->name = $userData['name'];
1147
            }
1148
            if (isset($userData['littlelink_name'])) {
1149
                $user->littlelink_name = $userData['littlelink_name'];
1150
            }
1151
            if (isset($userData['littlelink_description'])) {
1152
                $user->littlelink_description = $userData['littlelink_description'];
1153
            }
1154
            if (isset($userData['image_data'])) {
1155
                // Decode the image data from Base64
1156
                $imageData = base64_decode($userData['image_data']);
1157
                
1158
                // Save the image to the correct path with the correct file name and extension
1159
                $filename = $user->id . '.' . $userData['image_extension'];
1160
                file_put_contents(base_path('img/' . $filename), $imageData);
1161
                
1162
                // Update the user's image field with the correct file name
1163
                $user->image = $filename;
1164
            }
1165
            $user->save();
1166
    
1167
            // Delete all links for the authenticated user
1168
            Link::where('user_id', $user->id)->delete();
1169
    
1170
            // Loop through each link in $userData and create a new link for the user
1171
            foreach ($userData['links'] as $linkData) {
1172
1173
                $validatedData = Validator::make($linkData, [
1174
                    'link' => 'nullable|url',
1175
                ]);
1176
1177
                if ($validatedData->fails()) {
1178
                    throw new \Exception('Invalid link');
1179
                }
1180
1181
                $newLink = new Link();
1182
    
1183
                // Copy over the link data from $linkData to $newLink
1184
                $newLink->button_id = $linkData['button_id'];
1185
                $newLink->link = $linkData['link'];
1186
                
1187
                // Sanitize the title
1188
                if ($linkData['button_id'] == 93) {
1189
                    $sanitizedText = strip_tags($linkData['title'], '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
1190
                    $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
1191
                    $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
1192
                
1193
                    $newLink->title = $sanitizedText;
1194
                } else {
1195
                    $newLink->title = $linkData['title'];
1196
                }
1197
1198
                $newLink->order = $linkData['order'];
1199
                $newLink->click_number = 0;
1200
                $newLink->up_link = $linkData['up_link'];
1201
                $newLink->custom_css = $linkData['custom_css'];
1202
                $newLink->custom_icon = $linkData['custom_icon'];
1203
    
1204
                // Set the user ID to the current user's ID
1205
                $newLink->user_id = $user->id;
1206
    
1207
                // Save the new link to the database
1208
                $newLink->save();
1209
            }
1210
    
1211
            return redirect('studio/profile')->with('success', __('messages.Profile updated successfully!'));
1212
        } catch (\Exception $e) {
1213
            return redirect('studio/profile')->with('error', __('messages.An error occurred while updating your profile.'));
1214
        }
1215
    }
1216
    
1217
1218
    // Hanle reports
1219
    function report(Request $request)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1220
    {
1221
        $formData = $request->all();
1222
    
1223
        try {
1224
            Mail::to(env('ADMIN_EMAIL'))->send(new ReportSubmissionMail($formData));
1225
            
1226
            return redirect('report')->with('success', __('messages.report_success'));
1227
        } catch (\Exception $e) {
1228
            return redirect()->back()->with('error', __('messages.report_error'));
1229
        }
1230
    }
1231
1232
    //Edit/save page icons
1233
    public function editIcons(Request $request)
1234
    {
1235
        $inputKeys = array_keys($request->except('_token'));
1236
1237
        $validationRules = [];
1238
1239
        foreach ($inputKeys as $platform) {
1240
            $validationRules[$platform] = 'nullable|url|max:255';
1241
        }
1242
1243
        $request->validate($validationRules);
1244
1245
        foreach ($inputKeys as $platform) {
1246
            $link = $request->input($platform);
1247
1248
            if (!empty($link)) {
1249
                $iconId = $this->searchIcon($platform);
1250
1251
                if (!is_null($iconId)) {
1252
                    $this->updateIcon($platform, $link);
1253
                } else {
1254
                    $this->addIcon($platform, $link);
1255
                }
1256
            }
1257
        }
1258
1259
        return redirect('studio/links#icons');
1260
    }
1261
1262
    private function searchIcon($icon)
1263
    {
1264
        return DB::table('links')
1265
            ->where('user_id', Auth::id())
1266
            ->where('title', $icon)
1267
            ->where('button_id', 94)
1268
            ->value('id');
1269
    }
1270
1271
    private function addIcon($icon, $link)
1272
    {
1273
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
1274
        $links = new Link;
1275
        $links->link = $link;
1276
        $links->user_id = $userId;
1277
        $links->title = $icon;
1278
        $links->button_id = '94';
1279
        $links->save();
1280
        $links->order = ($links->id - 1);
1281
        $links->save();
1282
    }
1283
1284
    private function updateIcon($icon, $link)
1285
    {
1286
        Link::where('id', $this->searchIcon($icon))->update([
1287
            'button_id' => 94,
1288
            'link' => $link,
1289
            'title' => $icon
1290
        ]);
1291
    }
1292
}