aboutsummaryrefslogtreecommitdiff
path: root/cli/Commands/Checks/HelpTours.php
blob: b0c201ae37a476ca3d65db1e2a1a0055fc86b0ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php

namespace Studip\Cli\Commands\Checks;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class HelpTours extends Command
{
    protected static $defaultName = 'check:helptours';

    protected function configure(): void
    {
        $this->setDescription('Checks help tours for validity.');
        $this->setHelp('This command will check all active help tours if the sites used are still available');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        foreach (\HelpTour::findBySQL('1 ORDER BY name ASC') as $tour) {
            if (!$tour->settings->active) {
                if ($output->isVerbose()) {
                    $tour_name = $this->getTourName($tour);
                    $io->info("Skipping inactive tour {$tour_name}");
                }

                continue;
            }

            $errors = [];
            foreach ($tour->steps->orderBy('step ASC') as $step) {
                try {
                    if (match_route('plugins.php/*', $step->route)) {
                        $result = \PluginEngine::routeRequest(substr($step->route, strlen('plugins.php') + 1));

                        // retrieve corresponding plugin info
                        $plugin_manager = \PluginManager::getInstance();
                        $plugin_info = $plugin_manager->getPluginInfo($result[0]);

                        $file = implode('/', [
                            \Config::get()->PLUGINS_PATH,
                            $plugin_info['path'],
                            $plugin_info['class'],
                        ]);

                        if (file_exists($file . '.php')) {
                            $file .= '.php';
                        } elseif (file_exists($file . '.class.php')) {
                            $file .= '.class.php';
                        } else {
                            throw new \Exception();
                        }
                        require_once $file;
                        $plugin = new $plugin_info['class']();

                        if ($result[1]) {
                            $dispatcher = app(\Trails\Dispatcher::class);
                            $dispatcher->trails_root = $GLOBALS['ABSOLUTE_PATH_STUDIP'] . $plugin->getPluginPath();
                            $dispatcher->trails_uri = rtrim(\PluginEngine::getLink($plugin, [], null, true), '/');
                            $dispatcher->default_controller = 'index';
                            $dispatcher->current_plugin = $plugin;
                            $parsed = $dispatcher->parse($result[1]);
                            $controller = $dispatcher->load_controller($parsed[0]);
                            if ($parsed[1] && !$controller->has_action($parsed[1])) {
                                throw new \Exception();
                            }
                        }
                    } elseif (match_route('dispatch.php/*', $step->route)) {
                        $dispatcher = app(\Trails\Dispatcher::class);
                        $parsed = $dispatcher->parse(substr($step->route, strlen('dispatch.php') + 1));
                        $controller = $dispatcher->load_controller($parsed[0]);
                        if ($parsed[1] && !$controller->has_action($parsed[1])) {
                            throw new \Exception();
                        }
                    } elseif (!file_exists("{$GLOBALS['ABSOLUTE_PATH_STUDIP']}{$step->route}")) {
                        throw new \Exception();
                    }
                } catch (\Exception $e) {
                    $errors[$step->step] = $step->route;
                }
            }

            if ($errors) {
                $tour_name = $this->getTourName($tour);
                $io->error("{$tour_name} has errors in the following steps:");

                $io->table(
                    ['Step', 'Route'],
                    array_map(
                        function ($step, $route) {
                            return [$step, $route];
                        },
                        array_keys($errors),
                        array_values($errors)
                    )
                );
            }
        }

        return Command::SUCCESS;
    }

    private function getTourName(\HelpTour $tour)
    {
        $type = ucfirst($tour->type);
        return "{$type} '{$tour->name}' ({$tour->language})";
    }
}