Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
79.47% covered (warning)
79.47%
271 / 341
33.33% covered (danger)
33.33%
5 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
AppController
79.17% covered (warning)
79.17%
266 / 336
33.33% covered (danger)
33.33%
5 / 15
286.17
0.00% covered (danger)
0.00%
0 / 1
 getDeletedSets
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 getStartpage
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
5.01
 handleContribution
53.33% covered (warning)
53.33%
8 / 15
0.00% covered (danger)
0.00%
0 / 1
2.41
 getAllTags
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 encrypt
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 checkPictureLarge
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 checkPicture
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 saveDanSolveCondition
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
7
 updateSprintCondition
94.44% covered (success)
94.44%
17 / 18
0.00% covered (danger)
0.00%
0 / 1
4.00
 updateGoldenCondition
94.12% covered (success)
94.12%
16 / 17
0.00% covered (danger)
0.00%
0 / 1
3.00
 setPotionCondition
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 updateGems
72.84% covered (warning)
72.84%
59 / 81
0.00% covered (danger)
0.00%
0 / 1
91.26
 handleSearchSettings
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 signIn
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
2.02
 beforeFilter
87.50% covered (warning)
87.50%
105 / 120
0.00% covered (danger)
0.00%
0 / 1
48.96
 afterFilter
n/a
0 / 0
n/a
0 / 0
1
1<?php
2
3App::uses('Auth', 'Utility');
4App::uses('BoardSelector', 'Utility');
5App::uses('TsumegoFilters', 'Utility');
6App::uses('AchievementChecker', 'Utility');
7App::uses('TimeMode', 'Utility');
8
9class AppController extends Controller
10{
11    public $viewClass = 'App';
12
13    public $helpers = ['Pagination', 'AssetCompress.AssetCompress'];
14
15    public $components = [
16        //'DebugKit.Toolbar',
17        'PlayResultProcessor'
18    ];
19
20    protected function getDeletedSets()
21    {
22        $dSets = [];
23        $de = $this->Set->find('all', ['conditions' => ['public' => -1]]);
24        if (!$de)
25            $de = [];
26        foreach ($de as $item)
27            $dSets[] = $item['Set']['id'];
28
29        return $dSets;
30    }
31
32    public static function getStartpage(): string
33    {
34        $result = '';
35        $latest = ClassRegistry::init('AchievementStatus')->find('all', ['limit' => 7, 'order' => 'created DESC']) ?: [];
36        $latestCount = count($latest);
37        for ($i = 0; $i < $latestCount; $i++)
38        {
39            $a = ClassRegistry::init('Achievement')->findById($latest[$i]['AchievementStatus']['achievement_id']);
40            $u = ClassRegistry::init('User')->findById($latest[$i]['AchievementStatus']['user_id']);
41            if (substr($u['User']['name'], 0, 3) == 'g__' && $u['User']['external_id'] != null)
42                $startPageUser = AppController::checkPicture($u);
43            else
44                $startPageUser = $u['User']['name'];
45            $latest[$i]['AchievementStatus']['name'] = $a['Achievement']['name'];
46            $latest[$i]['AchievementStatus']['color'] = $a['Achievement']['color'];
47            $latest[$i]['AchievementStatus']['image'] = $a['Achievement']['image'];
48            $latest[$i]['AchievementStatus']['user'] = $startPageUser;
49            $result .= '<div class="quote1"><div class="quote1a"><a href="/achievements/view/' . $a['Achievement']['id'] . '"><img src="/img/' . $a['Achievement']['image'] . '.png" width="34px"></a></div>';
50            $result .= '<div class="quote1b">Achievement gained by ' . $startPageUser . ':<br><div class=""><b>' . $a['Achievement']['name'] . '</b></div></div></div>';
51        }
52        return $result;
53    }
54
55    /**
56     * @param int $uid User ID
57     * @param string $action Action type
58     *
59     * @return void
60     */
61    public static function handleContribution($uid, $action)
62    {
63        $uc = ClassRegistry::init('UserContribution')->find('first', ['conditions' => ['user_id' => $uid]]);
64        if ($uc == null)
65        {
66            $uc = [];
67            $uc['UserContribution']['user_id'] = $uid;
68            $uc['UserContribution']['created_tag'] = 0;
69            $uc['UserContribution']['made_proposal'] = 0;
70            $uc['UserContribution']['reviewed'] = 0;
71            $uc['UserContribution']['score'] = 0;
72            ClassRegistry::init('UserContribution')->create();
73        }
74        $uc['UserContribution'][$action] += 1;
75        $uc['UserContribution']['score']
76        = $uc['UserContribution']['created_tag'] * 3
77        + $uc['UserContribution']['made_proposal'] * 5
78        + $uc['UserContribution']['reviewed'] * 2;
79        ClassRegistry::init('UserContribution')->save($uc);
80    }
81
82    public static function getAllTags()
83    {
84        return Util::query("SELECT * from tag WHERE approved = 1 ORDER BY tag.name");
85    }
86
87    public static function encrypt($str = null)
88    {
89        $secret_key = 'my_simple_secret_keyx';
90        $secret_iv = 'my_simple_secret_ivx';
91        $encrypt_method = 'AES-256-CBC';
92        $key = hash('sha256', $secret_key);
93        $iv = substr(hash('sha256', $secret_iv), 0, 16);
94
95        return base64_encode(openssl_encrypt($str, $encrypt_method, $key, 0, $iv));
96    }
97
98    protected function checkPictureLarge($u)
99    {
100        if (substr($u['User']['name'], 0, 3) == 'g__' && $u['User']['external_id'] != null)
101            return substr($u['User']['name'], 3);
102
103        return $u['User']['name'];
104    }
105    public static function checkPicture($user)
106    {
107        if (substr($user['name'], 0, 3) == 'g__' && $user['external_id'] != null)
108            return substr($user['name'], 3);
109
110        return $user['name'];
111    }
112
113    public static function saveDanSolveCondition($solvedTsumegoRank, $tId): void
114    {
115        if ($solvedTsumegoRank == '1d' || $solvedTsumegoRank == '2d' || $solvedTsumegoRank == '3d' || $solvedTsumegoRank == '4d' || $solvedTsumegoRank == '5d')
116        {
117            $danSolveCategory = 'danSolve' . $solvedTsumegoRank;
118            $danSolveCondition = ClassRegistry::init('AchievementCondition')->find('first', [
119                'order' => 'value DESC',
120                'conditions' => [
121                    'user_id' => Auth::getUserID(),
122                    'category' => $danSolveCategory,
123                ],
124            ]);
125            if (!$danSolveCondition)
126            {
127                $danSolveCondition = [];
128                $danSolveCondition['AchievementCondition']['value'] = 0;
129                ClassRegistry::init('AchievementCondition')->create();
130            }
131            $danSolveCondition['AchievementCondition']['category'] = $danSolveCategory;
132            $danSolveCondition['AchievementCondition']['user_id'] = Auth::getUserID();
133            $danSolveCondition['AchievementCondition']['value']++;
134
135            ClassRegistry::init('AchievementCondition')->save($danSolveCondition);
136        }
137    }
138
139    public static function updateSprintCondition(bool $trigger = false): void
140    {
141        if (Auth::isLoggedIn())
142        {
143            $sprintCondition = ClassRegistry::init('AchievementCondition')->find('first', [
144                'order' => 'value DESC',
145                'conditions' => [
146                    'user_id' => Auth::getUserID(),
147                    'category' => 'sprint',
148                ],
149            ]);
150            if (!$sprintCondition)
151            {
152                $sprintCondition = [];
153                $sprintCondition['AchievementCondition']['value'] = 0;
154                ClassRegistry::init('AchievementCondition')->create();
155            }
156            $sprintCondition['AchievementCondition']['category'] = 'sprint';
157            $sprintCondition['AchievementCondition']['user_id'] = Auth::getUserID();
158            if ($trigger)
159                $sprintCondition['AchievementCondition']['value']++;
160            else
161                $sprintCondition['AchievementCondition']['value'] = 0;
162            ClassRegistry::init('AchievementCondition')->save($sprintCondition);
163        }
164    }
165
166    public static function updateGoldenCondition(bool $trigger = false): void
167    {
168        $goldenCondition = ClassRegistry::init('AchievementCondition')->find('first', [
169            'order' => 'value DESC',
170            'conditions' => [
171                'user_id' => Auth::getUserID(),
172                'category' => 'golden',
173            ],
174        ]);
175        if (!$goldenCondition)
176        {
177            $goldenCondition = [];
178            $goldenCondition['AchievementCondition']['value'] = 0;
179            ClassRegistry::init('AchievementCondition')->create();
180        }
181        $goldenCondition['AchievementCondition']['category'] = 'golden';
182        $goldenCondition['AchievementCondition']['user_id'] = Auth::getUserID();
183        if ($trigger)
184            $goldenCondition['AchievementCondition']['value']++;
185        else
186            $goldenCondition['AchievementCondition']['value'] = 0;
187        ClassRegistry::init('AchievementCondition')->save($goldenCondition);
188    }
189
190    public static function setPotionCondition(): void
191    {
192        $potionCondition = ClassRegistry::init('AchievementCondition')->find('first', [
193            'order' => 'value DESC',
194            'conditions' => [
195                'user_id' => Auth::getUserID(),
196                'category' => 'potion',
197            ],
198        ]);
199        if (!$potionCondition)
200        {
201            $potionCondition = [];
202            ClassRegistry::init('AchievementCondition')->create();
203        }
204        $potionCondition['AchievementCondition']['category'] = 'potion';
205        $potionCondition['AchievementCondition']['user_id'] = Auth::getUserID();
206        $potionCondition['AchievementCondition']['value'] = 1;
207        ClassRegistry::init('AchievementCondition')->save($potionCondition);
208    }
209
210    public static function updateGems(string $rank): void
211    {
212        $datex = new DateTime('today');
213        $today = $datex->format('Y-m-d');
214        $dateGem = ClassRegistry::init('DayRecord')->find('first', ['conditions' => ['date' => $today]]);
215        if ($dateGem != null)
216        {
217            $gems = explode('-', $dateGem['DayRecord']['gems']);
218            $gemValue = '';
219            $gemValue2 = '';
220            $gemValue3 = '';
221            $condition1 = 500;
222            $condition2 = 200;
223            $condition3 = 5;
224            $counterField = null; // Which counter to increment (gemCounter1, gemCounter2, or gemCounter3)
225            $achievementCategory = null;
226            $conditionMet = false;
227
228            if ($rank == '15k' || $rank == '14k' || $rank == '13k' || $rank == '12k' || $rank == '11k' || $rank == '10k')
229            {
230                if ($gems[0] == 0)
231                    $gemValue = '15k';
232                elseif ($gems[0] == 1)
233                    $gemValue = '12k';
234                elseif ($gems[0] == 2)
235                    $gemValue = '10k';
236                if ($rank == $gemValue)
237                {
238                    $counterField = 'gemCounter1';
239                    $achievementCategory = 'emerald';
240                    if ($dateGem['DayRecord']['gemCounter1'] + 1 == $condition1)
241                        $conditionMet = true;
242                }
243            }
244            elseif ($rank == '9k' || $rank == '8k' || $rank == '7k' || $rank == '6k' || $rank == '5k' || $rank == '4k' || $rank == '3k' || $rank == '2k' || $rank == '1k')
245            {
246                if ($gems[1] == 0)
247                {
248                    $gemValue = '9k';
249                    $gemValue2 = 'x';
250                    $gemValue3 = 'y';
251                }
252                elseif ($gems[1] == 1)
253                {
254                    $gemValue = '6k';
255                    $gemValue2 = '5k';
256                    $gemValue3 = '4k';
257                }
258                elseif ($gems[1] == 2)
259                {
260                    $gemValue = 'x';
261                    $gemValue2 = '2k';
262                    $gemValue3 = '1k';
263                }
264                if ($rank == $gemValue || $rank == $gemValue2 || $rank == $gemValue3)
265                {
266                    $counterField = 'gemCounter2';
267                    $achievementCategory = 'sapphire';
268                    if ($dateGem['DayRecord']['gemCounter2'] + 1 == $condition2)
269                        $conditionMet = true;
270                }
271            }
272            elseif ($rank == '1d' || $rank == '2d' || $rank == '3d' || $rank == '4d' || $rank == '5d' || $rank == '6d' || $rank == '7d')
273            {
274                if ($gems[2] == 0)
275                {
276                    $gemValue = '1d';
277                    $gemValue2 = '2d';
278                    $gemValue3 = '3d';
279                }
280                elseif ($gems[2] == 1)
281                {
282                    $gemValue = '2d';
283                    $gemValue2 = '3d';
284                    $gemValue3 = '4d';
285                }
286                elseif ($gems[2] == 2)
287                {
288                    $gemValue = '5d';
289                    $gemValue2 = '6d';
290                    $gemValue3 = '7d';
291                }
292                if ($rank == $gemValue || $rank == $gemValue2 || $rank == $gemValue3)
293                {
294                    $counterField = 'gemCounter3';
295                    $achievementCategory = 'ruby';
296                    if ($dateGem['DayRecord']['gemCounter3'] + 1 == $condition3)
297                        $conditionMet = true;
298                }
299            }
300
301            // If we matched a gem rank, update the counter atomically
302            if ($counterField !== null)
303            {
304                $increment = 1;
305                if ($conditionMet)
306                {
307                    $userHasAchievement = ClassRegistry::init('AchievementCondition')->find('first', [
308                        'order' => 'value DESC',
309                        'conditions' => [
310                            'user_id' => Auth::getUserID(),
311                            'category' => $achievementCategory,
312                        ],
313                    ]);
314                    if ($userHasAchievement == null)
315                    {
316                        $aCondition = [];
317                        $aCondition['AchievementCondition']['category'] = $achievementCategory;
318                        $aCondition['AchievementCondition']['user_id'] = Auth::getUserID();
319                        $aCondition['AchievementCondition']['value'] = 1;
320                        ClassRegistry::init('AchievementCondition')->save($aCondition);
321                    }
322                    else
323                        $increment = 0;
324                }
325
326                if ($increment > 0)
327                    ClassRegistry::init('DayRecord')->updateAll([$counterField => $counterField . ' + ' . $increment], ['date' => $today]);
328            }
329        }
330    }
331
332    /**
333     * @param int $uid User ID
334     * @return void
335     */
336    protected function handleSearchSettings($uid)
337    {
338        $this->loadModel('UserContribution');
339        $uc = $this->UserContribution->find('first', ['conditions' => ['user_id' => $uid]]);
340        if ($uc == null)
341        {
342            $uc = [];
343            $uc['UserContribution']['user_id'] = $uid;
344            $uc['UserContribution']['created_tag'] = 0;
345            $uc['UserContribution']['made_proposal'] = 0;
346            $uc['UserContribution']['reviewed'] = 0;
347            $uc['UserContribution']['score'] = 0;
348            $this->UserContribution->create();
349            $this->UserContribution->save($uc);
350        }
351        new TsumegoFilters();
352    }
353
354    protected function signIn(array $user): void
355    {
356        Auth::init($user);
357        $vs = $this->TsumegoStatus->find('first', ['conditions' => ['user_id' => $user['User']['id']], 'order' => 'updated DESC']);
358        if ($vs)
359            Util::setCookie('lastVisit', $vs['TsumegoStatus']['tsumego_id']);
360        Util::setCookie('texture', $user['User']['texture']);
361        Util::setCookie('check1', $user['User']['id']);
362    }
363
364    public function beforeFilter(): void
365    {
366        $this->loadModel('User');
367        $this->loadModel('Activate');
368        $this->loadModel('Tsumego');
369        $this->loadModel('Set');
370        $this->loadModel('TimeModeAttempt');
371        $this->loadModel('TsumegoStatus');
372        $this->loadModel('TsumegoAttempt');
373        $this->loadModel('AdminActivity');
374        $this->loadModel('Achievement');
375        $this->loadModel('AchievementStatus');
376        $this->loadModel('AchievementCondition');
377        $this->loadModel('SetConnection');
378        $this->loadModel('Tag');
379        $this->loadModel('Favorite');
380
381        Auth::init();
382        $timeMode = new TimeMode();
383
384        $highscoreLink = 'highscore';
385        $lightDark = 'light';
386        $resetCookies = false;
387        $levelBar = 1;
388        $lastProfileLeft = 1;
389        $lastProfileRight = 2;
390
391        if (Auth::isLoggedIn())
392        {
393            if ($lastTimeModeCategoryID = Util::clearCookie('lastTimeModeCategoryID'))
394                Auth::getUser()['last_time_mode_category_id'] = $lastTimeModeCategoryID;
395            if (isset($_COOKIE['z_sess']) && $_COOKIE['z_sess'] != 0
396            && strlen($_COOKIE['z_sess']) > 5)
397            {
398                Auth::getUser()['_sessid'] = $_COOKIE['z_sess'];
399                Auth::saveUser();
400            }
401            if (Auth::getUser()['lastHighscore'] == 1)
402                $highscoreLink = 'highscore';
403            elseif (Auth::getUser()['lastHighscore'] == 2)
404                $highscoreLink = 'rating';
405            elseif (Auth::getUser()['lastHighscore'] == 3)
406                $highscoreLink = 'leaderboard';
407            elseif (Auth::getUser()['lastHighscore'] == 4)
408                $highscoreLink = 'highscore3';
409
410            if (isset($_COOKIE['lastMode']) && $_COOKIE['lastMode'] != 0)
411            {
412                Auth::getUser()['lastMode'] = $_COOKIE['lastMode'];
413                Auth::saveUser();
414            }
415            if (isset($_COOKIE['sound']) && $_COOKIE['sound'] != '0')
416            {
417                Auth::getUser()['sound'] = $_COOKIE['sound'];
418                Auth::saveUser();
419                unset($_COOKIE['sound']);
420            }
421            $this->set('ac', true);
422            $this->set('user', Auth::getUser());
423        }
424
425        if (isset($_COOKIE['lightDark']) && $_COOKIE['lightDark'] != '0')
426        {
427            $lightDark = $_COOKIE['lightDark'];
428            if (Auth::isLoggedIn())
429            {
430                // Convert string to integer for database storage
431                $lightDarkInt = ($lightDark === 'light') ? 0 : 2;
432                Auth::getUser()['lastLight'] = $lightDarkInt;
433            }
434        }
435        elseif (Auth::isLoggedIn())
436            if (Auth::getUser()['lastLight'] == 0
437            || Auth::getUser()['lastLight'] == 1)
438                $lightDark = 'light';
439            else
440                $lightDark = 'dark';
441
442        if (Auth::isLoggedIn())
443        {
444            $this->handleSearchSettings(Auth::getUserID());
445            if (isset($_COOKIE['levelBar']) && $_COOKIE['levelBar'] != '0')
446            {
447                $levelBar = $_COOKIE['levelBar'];
448                Auth::getUser()['levelBar'] = $levelBar;
449            }
450            elseif (Auth::getUser()['levelBar'] == 0
451          || Auth::getUser()['levelBar'] == 'level')
452              $levelBar = 1;
453            else
454                $levelBar = 2;
455
456            if (isset($_COOKIE['lastProfileLeft']) && $_COOKIE['lastProfileLeft'] != '0')
457            {
458                $lastProfileLeft = $_COOKIE['lastProfileLeft'];
459                Auth::getUser()['lastProfileLeft'] = $lastProfileLeft;
460            }
461            else
462            {
463                $lastProfileLeft = Auth::getUser()['lastProfileLeft'];
464                if ($lastProfileLeft == 0)
465                    $lastProfileLeft = 1;
466            }
467            if (isset($_COOKIE['lastProfileRight']) && $_COOKIE['lastProfileRight'] != '0')
468            {
469                $lastProfileRight = $_COOKIE['lastProfileRight'];
470                Auth::getUser()['lastProfileRight'] = $lastProfileRight;
471            }
472            else
473            {
474                $lastProfileRight = Auth::getUser()['lastProfileRight'];
475                if ($lastProfileRight == 0)
476                    $lastProfileRight = 1;
477            }
478        }
479        $mode = 1;
480        if (isset($_COOKIE['mode']) && $_COOKIE['mode'] != '0')
481            if ($_COOKIE['mode'] == 1)
482                $mode = 1;
483            else
484                $mode = 2;
485
486        if (Auth::isLoggedIn() && Auth::getUser()['mode'] == 2)
487            $mode = 2;
488
489        if ($_COOKIE['sprint'] != 1)
490            $this->updateSprintCondition();
491
492        if (Auth::isLoggedIn() && !$this->request->is('ajax'))
493        {
494            $this->PlayResultProcessor->checkPreviousPlay($timeMode);
495            $achievementChecker = new AchievementChecker();
496            $achievementChecker->checkLevelAchievements();
497            $achievementChecker->checkProblemNumberAchievements();
498            $achievementChecker->checkRatingAchievements();
499            $achievementChecker->checkDanSolveAchievements();
500            $achievementChecker->checkNoErrorAchievements();
501            $achievementChecker->finalize();
502            $this->set('achievementUpdates', $achievementChecker->updated);
503        }
504        $boardNames = [];
505
506        if (!is_null($boardsBitmask = Util::clearCookie('boards_bitmask')))
507        {
508            if (Auth::isLoggedIn())
509            {
510                Auth::getUser()['boards_bitmask'] = BoardSelector::filterValidBits($boardsBitmask);
511                Auth::saveUser();
512            }
513        }
514        else
515            $boardsBitmask = BoardSelector::filterValidBits(Auth::isLoggedIn() ? Auth::getUser()['boards_bitmask'] : BoardSelector::$DEFAULT_BOARDS_BITMASK);
516
517        $this->set('boardsBitmask', $boardsBitmask);
518
519        $nextDay = new DateTime('tomorrow');
520        if (Auth::isLoggedIn())
521        {
522            $user = Auth::getUser();
523            $user['name'] = $this->checkPicture($user);
524            $this->set('user', $user);
525        }
526        $this->set('mode', $mode);
527        $this->set('nextDay', $nextDay->format('m/d/Y'));
528        $this->set('boardNames', $boardNames);
529        $this->set('highscoreLink', $highscoreLink);
530        $this->set('lightDark', $lightDark);
531        $this->set('levelBar', $levelBar);
532        $this->set('lastProfileLeft', $lastProfileLeft);
533        $this->set('lastProfileRight', $lastProfileRight);
534        $this->set('resetCookies', $resetCookies);
535        $this->set('timeMode', $timeMode);
536        if (Auth::isLoggedIn())
537            Auth::saveUser();
538    }
539
540    public function afterFilter() {}
541}