Passed
Push — main ( 0d4caa...434e6b )
by Julian
05:29
created

UserController::editLink()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 19
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 26
rs 9.3222
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')
107
        ->join('buttons', 'buttons.id', '=', 'links.button_id')
108
        ->select('links.*', 'buttons.name') // Assuming 'links.*' to fetch all columns including 'type_params'
109
        ->where('user_id', $id)
110
        ->orderBy('up_link', 'asc')
111
        ->orderBy('order', 'asc')
112
        ->get();
113
114
        // Loop through each link to decode 'type_params' and merge it into the link object
115
        foreach ($links as $link) {
116
            if (!empty($link->type_params)) {
117
                // Decode the JSON string into an associative array
118
                $typeParams = json_decode($link->type_params, true);
119
                if (is_array($typeParams)) {
120
                    // Merge the associative array into the link object
121
                    foreach ($typeParams as $key => $value) {
122
                        $link->$key = $value;
123
                    }
124
                }
125
            }
126
        }
127
128
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
129
    }
130
131
    //Show littlelink page as home page if set in config
132
    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

132
    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...
133
    {
134
        $littlelink_name = env('HOME_URL');
135
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
136
137
        if (empty($id)) {
138
            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...
139
        }
140
     
141
        $userinfo = User::select('id', 'name', 'littlelink_name', 'littlelink_description', 'theme', 'role', 'block')->where('id', $id)->first();
142
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
143
        
144
        $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();
145
146
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
147
    }
148
149
    //Redirect to user page
150
    public function userRedirect(request $request)
151
    {
152
        $id = $request->id;
153
        $user = User::select('littlelink_name')->where('id', $id)->value('littlelink_name');
154
155
        if (empty($id)) {
156
            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...
157
        }
158
     
159
        if (empty($user)) {
160
            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...
161
        }
162
163
        return redirect(url('@'.$user));
164
    }
165
166
    //Show add/update form
167
    public function AddUpdateLink($id = 0)
168
    {
169
        $linkData = $id ? Link::find($id) : new Link(['typename' => 'link', 'id' => '0']);
170
    
171
        $data = [
172
            'LinkTypes' => LinkType::get(),
173
            'LinkData' => $linkData,
174
            'LinkID' => $id,
175
            'linkTypeID' => "predefined",
176
            'title' => "Predefined Site",
177
        ];
178
179
        $data['typename'] = $linkData->type ?? 'predefined';
180
    
181
        return view('studio/edit-link', $data);
182
    }
183
184
    //Save add link
185
    public function saveLink(Request $request)
186
    {
187
        // Step 1: Validate Request
188
        // $request->validate([
189
        //     'link' => 'sometimes|url',
190
        // ]);
191
    
192
        // Step 2: Determine Link Type and Title
193
        $linkType = LinkType::findByTypename($request->typename);
194
        $LinkTitle = $request->title;
195
        $LinkURL = $request->link;
196
197
        // Step 3: Load Link Type Logic
198
        if($request->typename == 'predefined' || $request->typename == 'link') {
199
            // Determine button id based on whether a custom or predefined button is used
200
            $button_id = ($request->typename == 'link') ? ($request->GetSiteIcon == 1 ? 2 : 1) : null;
201
            $button = ($request->typename != 'link') ? Button::where('name', $request->button)->first() : null;
202
203
            $linkData = [
204
                'link' => $LinkURL,
205
                'title' => $LinkTitle ?? $button?->alt,
0 ignored issues
show
Bug introduced by
The property alt does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
Bug introduced by
The property alt does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
206
                '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...
207
                'button_id' => $button?->id ?? $button_id,
0 ignored issues
show
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
208
                'type' => $request->typename // Save the link type
209
            ];
210
        } else {
211
            $linkTypePath = base_path("blocks/{$linkType->typename}/handler.php");
0 ignored issues
show
Bug introduced by
The property typename does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
212
            if (file_exists($linkTypePath)) {
213
                include $linkTypePath;
214
                $result = handleLinkType($request, $linkType);
215
                
216
                // Extract rules and linkData from the result
217
                $rules = $result['rules'];
218
                $linkData = $result['linkData'];
219
            
220
                // Validate the request
221
                $validator = Validator::make($request->all(), $rules);
0 ignored issues
show
Bug introduced by
It seems like $rules can also be of type string; however, parameter $rules of Illuminate\Support\Facades\Validator::make() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

221
                $validator = Validator::make($request->all(), /** @scrutinizer ignore-type */ $rules);
Loading history...
222
223
                // Check if validation fails
224
                if ($validator->fails()) {
225
                    return back()->withErrors($validator)->withInput();
226
                }
227
228
                $linkData['button_id'] = $linkData['button_id'] ?? 1; // Set 'button_id' unless overwritten by handleLinkType
229
                $linkData['type'] = $linkType->typename; // Ensure 'type' is included in $linkData
230
            } else {
231
                abort(404, "Link type logic not found.");
232
            }
233
        }   
234
235
        // Step 4: Handle Custom Parameters
236
        // (Same as before)
237
238
        // Step 5: User and Button Information
239
        $userId = Auth::user()->id;
240
        $button = Button::where('name', $request->button)->first();
241
        if ($button && empty($LinkTitle)) $LinkTitle = $button->alt;
0 ignored issues
show
Unused Code introduced by
The assignment to $LinkTitle is dead and can be removed.
Loading history...
242
243
        // Step 6: Prepare Link Data
244
        // (Handled by the included file)
245
246
        // Step 7: Save or Update Link
247
        $OrigLink = Link::find($request->linkid);
248
        $linkColumns = Schema::getColumnListing('links'); // Get all column names of links table
249
        $filteredLinkData = array_intersect_key($linkData, array_flip($linkColumns)); // Filter $linkData to only include keys that are columns in the links table
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $linkData does not seem to be defined for all execution paths leading up to this point.
Loading history...
250
251
        // Combine remaining variables into one array and convert to JSON for the type_params column
252
        $customParams = array_diff_key($linkData, $filteredLinkData);
253
254
            // Check if $linkType->custom_html is defined and not null
255
            if (isset($linkType->custom_html)) {
256
                // Add $linkType->custom_html to the $customParams array
257
                $customParams['custom_html'] = $linkType->custom_html;
0 ignored issues
show
Bug introduced by
The property custom_html does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
258
            }
259
260
            // Check if $linkType->ignore_container is defined and not null
261
            if (isset($linkType->ignore_container)) {
262
                // Add $linkType->ignore_container to the $customParams array
263
                $customParams['ignore_container'] = $linkType->ignore_container;
0 ignored issues
show
Bug introduced by
The property ignore_container does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
264
            }
265
266
            // Check if $linkType->include_libraries is defined and not null
267
            if (isset($linkType->include_libraries)) {
268
                // Add $linkType->include_libraries to the $customParams array
269
                $customParams['include_libraries'] = $linkType->include_libraries;
0 ignored issues
show
Bug introduced by
The property include_libraries does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
270
            }
271
        
272
        $filteredLinkData['type_params'] = json_encode($customParams);
273
274
        if ($OrigLink) {
275
            $currentValues = $OrigLink->getAttributes();
276
            $nonNullFilteredLinkData = array_filter($filteredLinkData, function($value) {return !is_null($value);});
277
            $updatedValues = array_merge($currentValues, $nonNullFilteredLinkData);
278
            $OrigLink->update($updatedValues);
279
            $message = "Link updated";
280
        } else {
281
            $link = new Link($filteredLinkData);
282
            $link->user_id = $userId;
283
            $link->save();
284
            $message = "Link added";
285
        }
286
287
        // Step 8: Redirect
288
        $redirectUrl = $request->input('param') == 'add_more' ? 'studio/add-link' : 'studio/links';
289
        return Redirect($redirectUrl)->with('success', $message);
290
    }
291
    
292
    public function sortLinks(Request $request)
293
    {
294
        $linkOrders  = $request->input("linkOrders", []);
295
        $currentPage = $request->input("currentPage", 1);
296
        $perPage     = $request->input("perPage", 0);
297
298
        if ($perPage == 0) {
299
            $currentPage = 1;
300
        }
301
302
        $linkOrders = array_unique(array_filter($linkOrders));
303
        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...
304
            return response()->json([
305
                'status' => 'ERROR',
306
            ]);
307
        }
308
309
        $newOrder = $perPage * ($currentPage - 1);
310
        $linkNewOrders = [];
311
        foreach ($linkOrders as $linkId) {
312
            if ($linkId < 0) {
313
                continue;
314
            }
315
316
            $linkNewOrders[$linkId] = $newOrder;
317
            Link::where("id", $linkId)
318
                ->update([
319
                    'order' => $newOrder
320
                ]);
321
            $newOrder++;
322
        }
323
324
        return response()->json([
325
            'status' => 'OK',
326
            'linkOrders' => $linkNewOrders,
327
        ]);
328
    }
329
330
331
    //Count the number of clicks and redirect to link
332
    public function clickNumber(request $request)
333
    {
334
        $linkId = $request->id;
335
336
        if (substr($linkId, -1) == '+') {
337
            $linkWithoutPlus = str_replace('+', '', $linkId);
338
            return redirect(url('info/'.$linkWithoutPlus));
339
        }
340
    
341
        $link = Link::find($linkId);
342
343
        if (empty($link)) {
344
            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...
345
        }
346
347
        $link = $link->link;
348
349
        if (empty($linkId)) {
350
            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...
351
        }
352
353
        Link::where('id', $linkId)->increment('click_number', 1);
354
355
        $response = redirect()->away($link);
356
        $response->header('X-Robots-Tag', 'noindex, nofollow');
357
358
        return $response;
359
    }
360
361
    //Download Vcard
362
    public function vcard(request $request)
363
    {
364
        $linkId = $request->id;
365
366
        // Find the link with the specified ID
367
        $link = Link::findOrFail($linkId);
368
369
        $json = $link->link;
370
371
        // Decode the JSON to a PHP array
372
        $data = json_decode($json, true);
373
        
374
        // Create a new vCard object
375
        $vcard = new VCard();
376
        
377
        // Set the vCard properties from the $data array
378
        $vcard->addName($data['last_name'], $data['first_name'], $data['middle_name'], $data['prefix'], $data['suffix']);
379
        $vcard->addCompany($data['organization']);
380
        $vcard->addJobtitle($data['vtitle']);
381
        $vcard->addRole($data['role']);
382
        $vcard->addEmail($data['email']);
383
        $vcard->addEmail($data['work_email'], 'WORK');
384
        $vcard->addURL($data['work_url'], 'WORK');
385
        $vcard->addPhoneNumber($data['home_phone'], 'HOME');
386
        $vcard->addPhoneNumber($data['work_phone'], 'WORK');
387
        $vcard->addPhoneNumber($data['cell_phone'], 'CELL');
388
        $vcard->addAddress($data['home_address_street'], '', $data['home_address_city'], $data['home_address_state'], $data['home_address_zip'], $data['home_address_country'], 'HOME');
389
        $vcard->addAddress($data['work_address_street'], '', $data['work_address_city'], $data['work_address_state'], $data['work_address_zip'], $data['work_address_country'], 'WORK');
390
        
391
392
        // $vcard->addPhoto(base_path('img/1.png'));
393
        
394
        // Generate the vCard file contents
395
        $file_contents = $vcard->getOutput();
396
        
397
        // Set the file headers for download
398
        $headers = [
399
            'Content-Type' => 'text/x-vcard',
400
            'Content-Disposition' => 'attachment; filename="contact.vcf"'
401
        ];
402
        
403
        Link::where('id', $linkId)->increment('click_number', 1);
404
405
        // Return the file download response
406
        return response()->make($file_contents, 200, $headers);
407
408
    }
409
410
    //Show link, click number, up link in links page
411
    public function showLinks()
412
    {
413
        $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...
414
        $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...
415
        
416
        $data['links'] = Link::select()->where('user_id', $userId)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->paginate(99999);
417
        return view('studio/links', $data);
418
    }
419
420
    //Delete link
421
    public function deleteLink(request $request)
422
    {
423
        $linkId = $request->id;
424
425
        Link::where('id', $linkId)->delete();
426
427
        $directory = base_path("assets/favicon/icons");
428
        $files = scandir($directory);
429
        foreach($files as $file) {
430
        if (strpos($file, $linkId.".") !== false) {
431
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
432
        if (isset($pathinfo)) {
433
        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...
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...
434
        }
435
436
        return redirect('/studio/links');
437
    }
438
439
    //Delete icon
440
    public function clearIcon(request $request)
441
    {
442
        $linkId = $request->id;
443
444
        $directory = base_path("assets/favicon/icons");
445
        $files = scandir($directory);
446
        foreach($files as $file) {
447
        if (strpos($file, $linkId.".") !== false) {
448
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
449
        if (isset($pathinfo)) {
450
        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...
451
        }
452
453
        return redirect('/studio/links');
454
    }
455
456
    //Raise link on the littlelink page
457
    public function upLink(request $request)
458
    {
459
        $linkId = $request->id;
460
        $upLink = $request->up;
461
462
        if ($upLink == 'yes') {
463
            $up = 'no';
464
        } elseif ($upLink == 'no') {
465
            $up = 'yes';
466
        }
467
468
        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...
469
470
        return back();
471
    }
472
473
    //Show link to edit
474
    public function showLink(request $request)
475
    {
476
        $linkId = $request->id;
477
478
        $link = Link::where('id', $linkId)->value('link');
479
        $title = Link::where('id', $linkId)->value('title');
480
        $order = Link::where('id', $linkId)->value('order');
481
        $custom_css = Link::where('id', $linkId)->value('custom_css');
482
        $buttonId = Link::where('id', $linkId)->value('button_id');
483
        $buttonName = Button::where('id', $buttonId)->value('name');
484
485
        $buttons = Button::select('id', 'name')->orderBy('name', 'asc')->get();
486
487
        return view('studio/edit-link', ['custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId, 'buttonName' => $buttonName]);
488
    }
489
490
    //Show custom CSS + custom icon
491
    public function showCSS(request $request)
492
    {
493
        $linkId = $request->id;
494
495
        $link = Link::where('id', $linkId)->value('link');
496
        $title = Link::where('id', $linkId)->value('title');
497
        $order = Link::where('id', $linkId)->value('order');
498
        $custom_css = Link::where('id', $linkId)->value('custom_css');
499
        $custom_icon = Link::where('id', $linkId)->value('custom_icon');
500
        $buttonId = Link::where('id', $linkId)->value('button_id');
501
502
        $buttons = Button::select('id', 'name')->get();
503
504
        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]);
505
    }
506
507
    //Save edit link
508
    public function editLink(request $request)
509
    {
510
        $request->validate([
511
            'link' => 'required|exturl',
512
            'title' => 'required',
513
            'button' => 'required',
514
        ]);
515
516
        if (stringStartsWith($request->link, 'http://') == 'true' or stringStartsWith($request->link, 'https://') == 'true' or stringStartsWith($request->link, 'mailto:') == 'true')
517
            $link1 = $request->link;
518
        else
519
            $link1 = 'https://' . $request->link;
520
        if (stringEndsWith($request->link, '/') == 'true')
521
            $link = rtrim($link1, "/ ");
522
        else
523
        $link = $link1;
524
        $title = $request->title;
525
        $order = $request->order;
526
        $button = $request->button;
527
        $linkId = $request->id;
528
529
        $buttonId = Button::select('id')->where('name', $button)->value('id');
530
531
        Link::where('id', $linkId)->update(['link' => $link, 'title' => $title, 'order' => $order, 'button_id' => $buttonId]);
532
533
        return redirect('/studio/links');
534
    }
535
536
    //Save edit custom CSS + custom icon
537
    public function editCSS(request $request)
538
    {
539
        $linkId = $request->id;
540
        $custom_icon = $request->custom_icon;
541
        $custom_css = $request->custom_css;
542
543
        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...
544
            Link::where('id', $linkId)->update(['custom_icon' => $custom_icon]);
545
        } 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...
546
            Link::where('id', $linkId)->update(['custom_css' => $custom_css]);
547
        } else {
548
            Link::where('id', $linkId)->update([]);
549
        }
550
        return Redirect('#result');
551
    }
552
553
    //Show littlelinke page for edit
554
    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

554
    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...
555
    {
556
        $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...
557
558
        $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...
559
560
        return view('/studio/page', $data);
561
    }
562
563
    //Save littlelink page (name, description, logo)
564
    public function editPage(Request $request)
565
    {
566
        $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...
567
        $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...
568
    
569
        $validator = Validator::make($request->all(), [
570
            'littlelink_name' => [
571
                'sometimes',
572
                'max:255',
573
                'string',
574
                'isunique:users,id,'.$userId,
575
            ],
576
            'name' => 'sometimes|max:255|string',
577
            'image' => 'sometimes|image|mimes:jpeg,jpg,png,webp|max:2048', // Max file size: 2MB
578
        ], [
579
            'littlelink_name.unique' => __('messages.That handle has already been taken'),
580
            'image.image' => __('messages.The selected file must be an image'),
581
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP.',
582
            'image.max' => __('messages.The image size should not exceed 2MB'),
583
        ]);
584
    
585
        if ($validator->fails()) {
586
            return redirect('/studio/page')->withErrors($validator)->withInput();
587
        }
588
    
589
        $profilePhoto = $request->file('image');
590
        $pageName = $request->littlelink_name;
591
        $pageDescription = strip_tags($request->pageDescription, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
592
        $pageDescription = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $pageDescription);
593
        $pageDescription = strip_tags_except_allowed_protocols($pageDescription);
594
        $name = $request->name;
595
        $checkmark = $request->checkmark;
596
        $sharebtn = $request->sharebtn;
597
        $tablinks = $request->tablinks;
598
599
        if(env('HOME_URL') !== '' && $pageName != $littlelink_name && $littlelink_name == env('HOME_URL')){
600
            EnvEditor::editKey('HOME_URL', $pageName);
601
        }
602
    
603
        User::where('id', $userId)->update([
604
            'littlelink_name' => $pageName,
605
            'littlelink_description' => $pageDescription,
606
            'name' => $name
607
        ]);
608
    
609
        if ($request->hasFile('image')) {
610
611
            // Delete the user's current avatar if it exists
612
            while (findAvatar($userId) !== "error.error") {
613
                $avatarName = findAvatar($userId);
614
                unlink(base_path($avatarName));
615
            }
616
            
617
            $fileName = $userId . '_' . time() . "." . $profilePhoto->extension();
618
            $profilePhoto->move(base_path('assets/img'), $fileName);
619
        }
620
    
621
        if ($checkmark == "on") {
622
            UserData::saveData($userId, 'checkmark', true);
623
        } else {
624
            UserData::saveData($userId, 'checkmark', false);
625
        }
626
    
627
        if ($sharebtn == "on") {
628
            UserData::saveData($userId, 'disable-sharebtn', false);
629
        } else {
630
            UserData::saveData($userId, 'disable-sharebtn', true);
631
        }
632
633
        if ($tablinks == "on") {
634
            UserData::saveData($userId, 'links-new-tab', true);
635
        } else {
636
            UserData::saveData($userId, 'links-new-tab', false);
637
        }
638
    
639
        return Redirect('/studio/page');
640
    }
641
642
    //Upload custom theme background image
643
    public function themeBackground(Request $request)
644
    {
645
        $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...
646
        $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...
647
    
648
        $request->validate([
649
            'image' => 'required|image|mimes:jpeg,jpg,png,webp,gif|max:2048', // Max file size: 2MB
650
        ], [
651
            'image.required' => __('messages.Please select an image'),
652
            'image.image' => __('messages.The selected file must be an image'),
653
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP, GIF.',
654
            'image.max' => __('messages.The image size should not exceed 2MB'),
655
        ]);
656
    
657
        $customBackground = $request->file('image');
658
    
659
        if ($customBackground) {
660
            $directory = base_path('assets/img/background-img/');
661
            $files = scandir($directory);
662
            $pathinfo = "error.error";
0 ignored issues
show
Unused Code introduced by
The assignment to $pathinfo is dead and can be removed.
Loading history...
663
            foreach ($files as $file) {
664
                if (strpos($file, $userId . '.') !== false) {
665
                    $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

665
                    $pathinfo = $userId . "." . /** @scrutinizer ignore-type */ pathinfo($file, PATHINFO_EXTENSION);
Loading history...
666
                }
667
            }
668
    
669
            // Delete the user's current background image if it exists
670
            while (findBackground($userId) !== "error.error") {
671
                $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
672
                unlink(base_path($avatarName));
673
            }
674
                
675
            $fileName = $userId . '_' . time() . "." . $customBackground->extension();
676
            $customBackground->move(base_path('assets/img/background-img/'), $fileName);
677
    
678
            if (extension_loaded('imagick')) {
679
                $imagePath = base_path('assets/img/background-img/') . $fileName;
680
                $image = new \Imagick($imagePath);
681
                $image->stripImage();
682
                $image->writeImage($imagePath);
683
            }
684
    
685
            return redirect('/studio/theme');
686
        }
687
    
688
        return redirect('/studio/theme')->with('error', 'Please select a valid image file.');
689
    }
690
691
    //Delete custom background image
692
    public function removeBackground()
693
    {
694
        $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...
695
696
        // Delete the user's current background image if it exists
697
        while (findBackground($userId) !== "error.error") {
698
            $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
699
            unlink(base_path($avatarName));
700
        }
701
702
        return back();
703
    }
704
705
706
    //Show custom theme
707
    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

707
    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...
708
    {
709
        $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...
710
711
        $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...
712
713
        return view('/studio/theme', $data);
714
    }
715
716
    //Save custom theme
717
    public function editTheme(request $request)
718
    {
719
        $request->validate([
720
            'zip' => 'sometimes|mimes:zip',
721
        ]);
722
723
        $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...
724
725
        $zipfile = $request->file('zip');
726
727
        $theme = $request->theme;
728
        $message = "";
729
730
        User::where('id', $userId)->update(['theme' => $theme]);
731
732
733
734
        if (!empty($zipfile)) {
735
736
            $zipfile->move(base_path('/themes'), "temp.zip");
737
738
            $zip = new ZipArchive;
739
            $zip->open(base_path() . '/themes/temp.zip');
740
            $zip->extractTo(base_path() . '/themes');
741
            $zip->close();
742
            unlink(base_path() . '/themes/temp.zip');
743
744
            // Removes version numbers from folder.
745
746
            $folder = base_path('themes');
747
            $regex = '/[0-9.-]/';
748
            $files = scandir($folder);
749
750
            foreach ($files as $file) {
751
                $basename = basename($file);
752
                if (preg_match($regex, $basename)) {
753
                    $newBasename = preg_replace($regex, '', $basename);
754
                    $newPath = $folder . '/' . $newBasename;
755
                    File::copyDirectory($file, $newPath);
756
                    File::deleteDirectory($file);
757
                }
758
            }
759
        }
760
761
762
        return Redirect('/studio/theme')->with("success", $message);
763
    }
764
765
    //Show user (name, email, password)
766
    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

766
    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...
767
    {
768
        $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...
769
770
        $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...
771
772
        return view('/studio/profile', $data);
773
    }
774
775
    //Save user (name, email, password)
776
    public function editProfile(request $request)
777
    {
778
        $request->validate([
779
            'name' => 'sometimes|required|unique:users',
780
            'email' => 'sometimes|required|email|unique:users',
781
            'password' => 'sometimes|min:8',
782
        ]);
783
784
        $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...
785
786
        $name = $request->name;
787
        $email = $request->email;
788
        $password = Hash::make($request->password);
789
790
        if ($request->name != '') {
791
            User::where('id', $userId)->update(['name' => $name]);
792
        } elseif ($request->email != '') {
793
            User::where('id', $userId)->update(['email' => $email]);
794
        } elseif ($request->password != '') {
795
            User::where('id', $userId)->update(['password' => $password]);
796
            Auth::logout();
797
        }
798
        return back();
799
    }
800
801
    //Show user theme credit page
802
    public function theme(request $request)
803
    {
804
        $littlelink_name = $request->littlelink;
805
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
806
807
        if (empty($id)) {
808
            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...
809
        }
810
811
        $userinfo = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->first();
812
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
813
814
        $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();
815
816
        return view('components/theme', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
817
    }
818
819
    //Delete existing user
820
    public function deleteUser(request $request)
821
    {
822
823
        // echo $request->id;
824
        // echo "<br>";
825
        // echo Auth::id();
826
        $id = $request->id;
827
828
    if($id == Auth::id() and $id != "1") {
829
830
        Link::where('user_id', $id)->delete();
831
832
        $user = User::find($id);
833
834
        Schema::disableForeignKeyConstraints();
835
        $user->forceDelete();
836
        Schema::enableForeignKeyConstraints();
837
    }
838
839
        return redirect('/');
840
    }
841
842
    //Delete profile picture
843
    public function delProfilePicture()
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
847
        // Delete the user's current avatar if it exists
848
        while (findAvatar($userId) !== "error.error") {
849
            $avatarName = findAvatar($userId);
850
            unlink(base_path($avatarName));
851
        }
852
853
        return back();
854
    }
855
856
    //Export user links
857
    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

857
    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...
858
    {
859
        $userId = Auth::id();
860
        $user = User::find($userId);
861
        $links = Link::where('user_id', $userId)->get();
862
        
863
        if (!$user) {
864
            // handle the case where the user is null
865
            return response()->json(['message' => 'User not found'], 404);
866
        }
867
868
        $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...
869
870
        $domain = $_SERVER['HTTP_HOST'];
871
        $date = date('Y-m-d_H-i-s');
872
        $fileName = "links-$domain-$date.json";
873
        $headers = [
874
            'Content-Type' => 'application/json',
875
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
876
        ];
877
        return response()->json($userData, 200, $headers);
878
879
        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...
880
    }
881
882
    //Export all user data
883
    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

883
    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...
884
    {
885
        $userId = Auth::id();
886
        $user = User::find($userId);
887
        $links = Link::where('user_id', $userId)->get();
888
    
889
        if (!$user) {
890
            // handle the case where the user is null
891
            return response()->json(['message' => 'User not found'], 404);
892
        }
893
    
894
        $userData = $user->toArray();
895
        $userData['links'] = $links->toArray();
896
897
        if (file_exists(base_path(findAvatar($userId)))){
898
            $imagePath = base_path(findAvatar($userId));
899
            $imageData = base64_encode(file_get_contents($imagePath));
900
            $userData['image_data'] = $imageData;
901
    
902
            $imageExtension = pathinfo($imagePath, PATHINFO_EXTENSION);
903
            $userData['image_extension'] = $imageExtension;
904
        }
905
    
906
        $domain = $_SERVER['HTTP_HOST'];
907
        $date = date('Y-m-d_H-i-s');
908
        $fileName = "user_data-$domain-$date.json";
909
        $headers = [
910
            'Content-Type' => 'application/json',
911
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
912
        ];
913
        return response()->json($userData, 200, $headers);
914
    
915
        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...
916
    }    
917
918
    public function importData(Request $request)
919
    {
920
        try {
921
            // Get the JSON data from the uploaded file
922
            if (!$request->hasFile('import') || !$request->file('import')->isValid()) {
923
                throw new \Exception('File not uploaded or is faulty');
924
            }
925
            $file = $request->file('import');
926
            $jsonString = $file->get();
927
            $userData = json_decode($jsonString, true);
928
    
929
            // Update the authenticated user's profile data if defined in the JSON file
930
            $user = auth()->user();
931
            if (isset($userData['name'])) {
932
                $user->name = $userData['name'];
933
            }
934
935
            if (isset($userData['littlelink_description'])) {
936
                $sanitizedText = $userData['littlelink_description'];
937
                $sanitizedText = strip_tags($sanitizedText, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
938
                $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
939
                $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
940
                $user->littlelink_description = $sanitizedText;
941
            }
942
943
            if (isset($userData['image_data'])) {
944
945
                $allowedExtensions = array('jpeg', 'jpg', 'png', 'webp');
946
                $userExtension = strtolower($userData['image_extension']);
947
948
                if (in_array($userExtension, $allowedExtensions)) {
949
                // Decode the image data from Base64
950
                $imageData = base64_decode($userData['image_data']);
951
952
                // Delete the user's current avatar if it exists
953
                while (findAvatar(Auth::id()) !== "error.error") {
954
                    $avatarName = findAvatar(Auth::id());
955
                    unlink(base_path($avatarName));
956
                }
957
                
958
                // Save the image to the correct path with the correct file name and extension
959
                $filename = $user->id . '.' . $userExtension;
960
                file_put_contents(base_path('assets/img/' . $filename), $imageData);
961
                
962
                // Update the user's image field with the correct file name
963
                $user->image = $filename;
964
                }
965
            }
966
967
            $user->save();
968
    
969
            // Delete all links for the authenticated user
970
            Link::where('user_id', $user->id)->delete();
971
    
972
            // Loop through each link in $userData and create a new link for the user
973
            foreach ($userData['links'] as $linkData) {
974
975
                $validatedData = Validator::make($linkData, [
976
                    'link' => 'nullable|exturl',
977
                ]);
978
979
                if ($validatedData->fails()) {
980
                    throw new \Exception('Invalid link');
981
                }
982
983
                $newLink = new Link();
984
    
985
                // Copy over the link data from $linkData to $newLink
986
                $newLink->button_id = $linkData['button_id'];
987
                $newLink->link = $linkData['link'];
988
                
989
                // Sanitize the title
990
                if ($linkData['button_id'] == 93) {
991
                    $sanitizedText = strip_tags($linkData['title'], '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
992
                    $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
993
                    $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
994
                
995
                    $newLink->title = $sanitizedText;
996
                } else {
997
                    $newLink->title = $linkData['title'];
998
                }
999
1000
                $newLink->order = $linkData['order'];
1001
                $newLink->click_number = 0;
1002
                $newLink->up_link = $linkData['up_link'];
1003
                $newLink->custom_css = $linkData['custom_css'];
1004
                $newLink->custom_icon = $linkData['custom_icon'];
1005
                $newLink->type = $linkData['type'];
1006
                $newLink->type_params = $linkData['type_params'];
1007
    
1008
                // Set the user ID to the current user's ID
1009
                $newLink->user_id = $user->id;
1010
    
1011
                // Save the new link to the database
1012
                $newLink->save();
1013
            }
1014
            return redirect('studio/profile')->with('success', __('messages.Profile updated successfully!'));
1015
        } catch (\Exception $e) {
1016
            return redirect('studio/profile')->with('error', __('messages.An error occurred while updating your profile.'));
1017
        }
1018
    }
1019
    
1020
1021
    // Hanle reports
1022
    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...
1023
    {
1024
        $formData = $request->all();
1025
    
1026
        try {
1027
            Mail::to(env('ADMIN_EMAIL'))->send(new ReportSubmissionMail($formData));
1028
            
1029
            return redirect('report')->with('success', __('messages.report_success'));
1030
        } catch (\Exception $e) {
1031
            return redirect()->back()->with('error', __('messages.report_error'));
1032
        }
1033
    }
1034
1035
    //Edit/save page icons
1036
    public function editIcons(Request $request)
1037
    {
1038
        $inputKeys = array_keys($request->except('_token'));
1039
1040
        $validationRules = [];
1041
1042
        foreach ($inputKeys as $platform) {
1043
            $validationRules[$platform] = 'nullable|exturl|max:255';
1044
        }
1045
1046
        $request->validate($validationRules);
1047
1048
        foreach ($inputKeys as $platform) {
1049
            $link = $request->input($platform);
1050
1051
            if (!empty($link)) {
1052
                $iconId = $this->searchIcon($platform);
1053
1054
                if (!is_null($iconId)) {
1055
                    $this->updateIcon($platform, $link);
1056
                } else {
1057
                    $this->addIcon($platform, $link);
1058
                }
1059
            }
1060
        }
1061
1062
        return redirect('studio/links#icons');
1063
    }
1064
1065
    private function searchIcon($icon)
1066
    {
1067
        return DB::table('links')
1068
            ->where('user_id', Auth::id())
1069
            ->where('title', $icon)
1070
            ->where('button_id', 94)
1071
            ->value('id');
1072
    }
1073
1074
    private function addIcon($icon, $link)
1075
    {
1076
        $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...
1077
        $links = new Link;
1078
        $links->link = $link;
1079
        $links->user_id = $userId;
1080
        $links->title = $icon;
1081
        $links->button_id = '94';
1082
        $links->save();
1083
        $links->order = ($links->id - 1);
1084
        $links->save();
1085
    }
1086
1087
    private function updateIcon($icon, $link)
1088
    {
1089
        Link::where('id', $this->searchIcon($icon))->update([
1090
            'button_id' => 94,
1091
            'link' => $link,
1092
            'title' => $icon
1093
        ]);
1094
    }
1095
}