Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 314
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
acp_modules
0.00% covered (danger)
0.00%
0 / 314
0.00% covered (danger)
0.00%
0 / 2
8742
0.00% covered (danger)
0.00%
0 / 1
 main
0.00% covered (danger)
0.00%
0 / 283
0.00% covered (danger)
0.00%
0 / 1
5402
 make_module_select
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
420
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14/**
15* @ignore
16*/
17if (!defined('IN_PHPBB'))
18{
19    exit;
20}
21
22use phpbb\module\exception\module_exception;
23
24/**
25* - Able to check for new module versions (modes changed/adjusted/added/removed)
26* Icons for:
27* - module enabled and displayed (common)
28* - module enabled and not displayed
29* - module deactivated
30* - category (enabled)
31* - category disabled
32*/
33
34class acp_modules
35{
36    var $module_class = '';
37    var $parent_id;
38    var $u_action;
39
40    function main($id, $mode)
41    {
42        global $db, $user, $template, $module, $request, $phpbb_log, $phpbb_container;
43
44        /** @var \phpbb\module\module_manager $module_manager */
45        $module_manager = $phpbb_container->get('module.manager');
46
47        // Set a global define for modules we might include (the author is able to prevent execution of code by checking this constant)
48        define('MODULE_INCLUDE', true);
49
50        $user->add_lang('acp/modules');
51        $this->tpl_name = 'acp_modules';
52
53        $form_key = 'acp_modules';
54        add_form_key($form_key);
55
56        // module class
57        $this->module_class = $mode;
58
59        if ($this->module_class == 'ucp')
60        {
61            $user->add_lang('ucp');
62        }
63        else if ($this->module_class == 'mcp')
64        {
65            $user->add_lang('mcp');
66        }
67
68        if ($module->p_class != $this->module_class)
69        {
70            $module->add_mod_info($this->module_class);
71        }
72
73        $this->page_title = strtoupper($this->module_class);
74
75        $this->parent_id = $request->variable('parent_id', 0);
76        $module_id = $request->variable('m', 0);
77        $action = $request->variable('action', '');
78
79        switch ($action)
80        {
81            case 'delete':
82                if (!$module_id)
83                {
84                    trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
85                }
86
87                if (confirm_box(true))
88                {
89                    // Make sure we are not directly within a module
90                    if ($module_id == $this->parent_id)
91                    {
92                        $sql = 'SELECT parent_id
93                            FROM ' . MODULES_TABLE . '
94                            WHERE module_id = ' . $module_id;
95                        $result = $db->sql_query($sql);
96                        $this->parent_id = (int) $db->sql_fetchfield('parent_id');
97                        $db->sql_freeresult($result);
98                    }
99
100                    try
101                    {
102                        $row = $module_manager->get_module_row($module_id, $this->module_class);
103                        $module_manager->delete_module($module_id, $this->module_class);
104                        $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_REMOVED', false, array($user->lang($row['module_langname'])));
105                    }
106                    catch (module_exception $e)
107                    {
108                        $msg = $user->lang($e->getMessage());
109                        trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
110                    }
111
112                    $module_manager->remove_cache_file($this->module_class);
113                    trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
114                }
115                else
116                {
117                    confirm_box(false, 'DELETE_MODULE', build_hidden_fields(array(
118                        'i'            => $id,
119                        'mode'        => $mode,
120                        'parent_id'    => $this->parent_id,
121                        'module_id'    => $module_id,
122                        'action'    => $action,
123                    )));
124                }
125
126            break;
127
128            case 'enable':
129            case 'disable':
130                if (!$module_id)
131                {
132                    trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
133                }
134
135                if (!check_link_hash($request->variable('hash', ''), 'acp_modules'))
136                {
137                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
138                }
139
140                $sql = 'SELECT *
141                    FROM ' . MODULES_TABLE . "
142                    WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
143                        AND module_id = $module_id";
144                $result = $db->sql_query($sql);
145                $row = $db->sql_fetchrow($result);
146                $db->sql_freeresult($result);
147
148                if (!$row)
149                {
150                    trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
151                }
152
153                $sql = 'UPDATE ' . MODULES_TABLE . '
154                    SET module_enabled = ' . (($action == 'enable') ? 1 : 0) . "
155                    WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
156                        AND module_id = $module_id";
157                $db->sql_query($sql);
158
159                $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($user->lang($row['module_langname'])));
160                $module_manager->remove_cache_file($this->module_class);
161
162            break;
163
164            case 'move_up':
165            case 'move_down':
166                if (!$module_id)
167                {
168                    trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
169                }
170
171                if (!check_link_hash($request->variable('hash', ''), 'acp_modules'))
172                {
173                    trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
174                }
175
176                $sql = 'SELECT *
177                    FROM ' . MODULES_TABLE . "
178                    WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
179                        AND module_id = $module_id";
180                $result = $db->sql_query($sql);
181                $row = $db->sql_fetchrow($result);
182                $db->sql_freeresult($result);
183
184                if (!$row)
185                {
186                    trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
187                }
188
189                try
190                {
191                    $move_module_name = $module_manager->move_module_by($row, $this->module_class, $action, 1);
192
193                    $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_' . strtoupper($action), false, array($user->lang($row['module_langname']), $move_module_name));
194                    $module_manager->remove_cache_file($this->module_class);
195                }
196                catch (module_exception $e)
197                {
198                    // Do nothing
199                }
200
201                if ($request->is_ajax())
202                {
203                    $json_response = new \phpbb\json_response;
204                    $json_response->send(array(
205                        'success'    => ($move_module_name !== false),
206                    ));
207                }
208
209            break;
210
211            case 'quickadd':
212                $quick_install = $request->variable('quick_install', '');
213
214                if (confirm_box(true))
215                {
216                    if (!$quick_install || strpos($quick_install, '::') === false)
217                    {
218                        break;
219                    }
220
221                    list($module_basename, $module_mode) = explode('::', $quick_install);
222
223                    // Check if module name and mode exist...
224                    $fileinfo = $module_manager->get_module_infos($this->module_class, $module_basename);
225                    $fileinfo = $fileinfo[$module_basename];
226
227                    if (isset($fileinfo['modes'][$module_mode]))
228                    {
229                        $module_data = array(
230                            'module_basename'    => $module_basename,
231                            'module_enabled'    => 0,
232                            'module_display'    => (isset($fileinfo['modes'][$module_mode]['display'])) ? $fileinfo['modes'][$module_mode]['display'] : 1,
233                            'parent_id'            => $this->parent_id,
234                            'module_class'        => $this->module_class,
235                            'module_langname'    => $fileinfo['modes'][$module_mode]['title'],
236                            'module_mode'        => $module_mode,
237                            'module_auth'        => $fileinfo['modes'][$module_mode]['auth'],
238                        );
239
240                        try
241                        {
242                            $module_manager->update_module_data($module_data);
243                            $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_MODULE_ADD', false, array($user->lang($module_data['module_langname'])));
244                        }
245                        catch (\phpbb\module\exception\module_exception $e)
246                        {
247                            $msg = $user->lang($e->getMessage());
248                            trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
249                        }
250
251                        $module_manager->remove_cache_file($this->module_class);
252                        trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
253                    }
254                }
255                else
256                {
257                    confirm_box(false, 'ADD_MODULE', build_hidden_fields(array(
258                        'i'            => $id,
259                        'mode'        => $mode,
260                        'parent_id'    => $this->parent_id,
261                        'action'    => 'quickadd',
262                        'quick_install'    => $quick_install,
263                    )));
264                }
265
266            break;
267
268            case 'edit':
269
270                if (!$module_id)
271                {
272                    trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
273                }
274
275                try
276                {
277                    $module_row = $module_manager->get_module_row($module_id, $this->module_class);
278                }
279                catch (\phpbb\module\exception\module_not_found_exception $e)
280                {
281                    $msg = $user->lang($e->getMessage());
282                    trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
283                }
284
285            // no break
286
287            case 'add':
288
289                if ($action == 'add')
290                {
291                    $module_row = array(
292                        'module_basename'    => '',
293                        'module_enabled'    => 0,
294                        'module_display'    => 1,
295                        'parent_id'            => 0,
296                        'module_langname'    => $request->variable('module_langname', '', true),
297                        'module_mode'        => '',
298                        'module_auth'        => '',
299                    );
300                }
301
302                $module_data = array();
303
304                $module_data['module_basename'] = $request->variable('module_basename', (string) $module_row['module_basename']);
305                $module_data['module_enabled'] = $request->variable('module_enabled', (int) $module_row['module_enabled']);
306                $module_data['module_display'] = $request->variable('module_display', (int) $module_row['module_display']);
307                $module_data['parent_id'] = $request->variable('module_parent_id', (int) $module_row['parent_id']);
308                $module_data['module_class'] = $this->module_class;
309                $module_data['module_langname'] = $request->variable('module_langname', (string) $module_row['module_langname'], true);
310                $module_data['module_mode'] = $request->variable('module_mode', (string) $module_row['module_mode']);
311
312                $submit = (isset($_POST['submit'])) ? true : false;
313
314                if ($submit)
315                {
316                    if (!check_form_key($form_key))
317                    {
318                        trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
319                    }
320
321                    if (!$module_data['module_langname'])
322                    {
323                        trigger_error($user->lang['NO_MODULE_LANGNAME'] . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
324                    }
325
326                    $module_type = $request->variable('module_type', 'category');
327
328                    if ($module_type == 'category')
329                    {
330                        $module_data['module_basename'] = $module_data['module_mode'] = $module_data['module_auth'] = '';
331                        $module_data['module_display'] = 1;
332                    }
333
334                    if ($action == 'edit')
335                    {
336                        $module_data['module_id'] = $module_id;
337                    }
338
339                    // Adjust auth row
340                    if ($module_data['module_basename'] && $module_data['module_mode'])
341                    {
342                        $fileinfo = $module_manager->get_module_infos($this->module_class, $module_data['module_basename']);
343                        $module_data['module_auth'] = $fileinfo[$module_data['module_basename']]['modes'][$module_data['module_mode']]['auth'];
344                    }
345
346                    try
347                    {
348                        $module_manager->update_module_data($module_data);
349                        $phpbb_log->add('admin',
350                            $user->data['user_id'],
351                            $user->ip,
352                            ($action === 'edit') ? 'LOG_MODULE_EDIT' : 'LOG_MODULE_ADD',
353                            false,
354                            array($user->lang($module_data['module_langname']))
355                        );                    }
356                    catch (\phpbb\module\exception\module_exception $e)
357                    {
358                        $msg = $user->lang($e->getMessage());
359                        trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
360                    }
361
362                    $module_manager->remove_cache_file($this->module_class);
363                    trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
364                }
365
366                // Category/not category?
367                $is_cat = (!$module_data['module_basename']) ? true : false;
368
369                // Get module information
370                $module_infos = $module_manager->get_module_infos($this->module_class);
371
372                // Build name options
373                $s_name_options = $s_mode_options = '';
374                foreach ($module_infos as $option => $values)
375                {
376                    if (!$module_data['module_basename'])
377                    {
378                        $module_data['module_basename'] = $option;
379                    }
380
381                    // Name options
382                    $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $user->lang($values['title']) . ' [' . $option . ']</option>';
383
384                    $template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option)));
385
386                    // Build module modes
387                    foreach ($values['modes'] as $m_mode => $m_values)
388                    {
389                        if ($option == $module_data['module_basename'])
390                        {
391                            $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $user->lang($m_values['title']) . '</option>';
392                        }
393
394                        $template->assign_block_vars('m_names.modes', array(
395                            'OPTION'        => $m_mode,
396                            'VALUE'            => $user->lang($m_values['title']),
397                            'A_OPTION'        => addslashes($m_mode),
398                            'A_VALUE'        => addslashes($user->lang($m_values['title'])))
399                        );
400                    }
401                }
402
403                $s_cat_option = '<option value="0"' . (($module_data['parent_id'] == 0) ? ' selected="selected"' : '') . '>' . $user->lang['NO_PARENT'] . '</option>';
404
405                $template->assign_vars(array_merge(array(
406                    'S_EDIT_MODULE'        => true,
407                    'S_IS_CAT'            => $is_cat,
408                    'S_CAT_OPTIONS'        => $s_cat_option . $this->make_module_select($module_data['parent_id'], ($action == 'edit') ? $module_row['module_id'] : false, false, false, false, true),
409                    'S_MODULE_NAMES'    => $s_name_options,
410                    'S_MODULE_MODES'    => $s_mode_options,
411                    'U_BACK'            => $this->u_action . '&amp;parent_id=' . $this->parent_id,
412                    'U_EDIT_ACTION'        => $this->u_action . '&amp;parent_id=' . $this->parent_id,
413
414                    'L_TITLE'            => $user->lang[strtoupper($action) . '_MODULE'],
415
416                    'MODULENAME'        => $user->lang($module_data['module_langname']),
417                    'ACTION'            => $action,
418                    'MODULE_ID'            => $module_id,
419
420                ),
421                    array_change_key_case($module_data, CASE_UPPER))
422                );
423
424                return;
425
426            break;
427        }
428
429        if (!$this->parent_id)
430        {
431            $navigation = strtoupper($this->module_class);
432        }
433        else
434        {
435            $navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>';
436
437            $modules_nav = $module_manager->get_module_branch($this->parent_id, $this->module_class, 'parents');
438
439            foreach ($modules_nav as $row)
440            {
441                $langname = $user->lang($row['module_langname']);
442
443                if ($row['module_id'] == $this->parent_id)
444                {
445                    $navigation .= ' -&gt; ' . $langname;
446                }
447                else
448                {
449                    $navigation .= ' -&gt; <a href="' . $this->u_action . '&amp;parent_id=' . $row['module_id'] . '">' . $langname . '</a>';
450                }
451            }
452        }
453
454        // Jumpbox
455        $module_box = $this->make_module_select($this->parent_id, false, false, false, false);
456
457        $sql = 'SELECT *
458            FROM ' . MODULES_TABLE . "
459            WHERE parent_id = {$this->parent_id}
460                AND module_class = '" . $db->sql_escape($this->module_class) . "'
461            ORDER BY left_id";
462        $result = $db->sql_query($sql);
463
464        if ($row = $db->sql_fetchrow($result))
465        {
466            do
467            {
468                $langname = $user->lang($row['module_langname']);
469
470                $url = $this->u_action . '&amp;parent_id=' . $this->parent_id . '&amp;m=' . $row['module_id'];
471
472                $template->assign_block_vars('modules', array(
473                    'MODULE_TITLE'        => $langname,
474                    'MODULE_ENABLED'    => ($row['module_enabled']) ? true : false,
475                    'MODULE_DISPLAYED'    => ($row['module_display']) ? true : false,
476
477                    'S_ACP_CAT_SYSTEM'            => ($this->module_class == 'acp' && $row['module_langname'] == 'ACP_CAT_SYSTEM') ? true : false,
478                    'S_ACP_MODULE_MANAGEMENT'    => ($this->module_class == 'acp' && ($row['module_basename'] == 'modules' || $row['module_langname'] == 'ACP_MODULE_MANAGEMENT')) ? true : false,
479
480                    'S_SUB_MODULE'        => (!$row['module_basename'] || $row['left_id'] + 1 != $row['right_id']) ? true : false,
481
482                    'U_MODULE'            => $this->u_action . '&amp;parent_id=' . $row['module_id'],
483                    'U_MOVE_UP'            => $url . '&amp;action=move_up&amp;hash=' . generate_link_hash('acp_modules'),
484                    'U_MOVE_DOWN'        => $url . '&amp;action=move_down&amp;hash=' . generate_link_hash('acp_modules'),
485                    'U_EDIT'            => $url . '&amp;action=edit',
486                    'U_DELETE'            => $url . '&amp;action=delete',
487                    'U_ENABLE'            => $url . '&amp;action=enable&amp;hash=' . generate_link_hash('acp_modules'),
488                    'U_DISABLE'            => $url . '&amp;action=disable&amp;hash=' . generate_link_hash('acp_modules'))
489                );
490            }
491            while ($row = $db->sql_fetchrow($result));
492        }
493        else if ($this->parent_id)
494        {
495            try
496            {
497                $row = $module_manager->get_module_row($this->parent_id, $this->module_class);
498            }
499            catch (\phpbb\module\exception\module_not_found_exception $e)
500            {
501                $msg = $user->lang($e->getMessage());
502                trigger_error($msg . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
503            }
504
505            $url = $this->u_action . '&amp;parent_id=' . $this->parent_id . '&amp;m=' . $row['module_id'];
506
507            $template->assign_vars(array(
508                'S_NO_MODULES'        => true,
509                'MODULE_TITLE'        => $langname,
510                'MODULE_ENABLED'    => ($row['module_enabled']) ? true : false,
511                'MODULE_DISPLAYED'    => ($row['module_display']) ? true : false,
512
513                'U_EDIT'            => $url . '&amp;action=edit',
514                'U_DELETE'            => $url . '&amp;action=delete',
515                'U_ENABLE'            => $url . '&amp;action=enable&amp;hash=' . generate_link_hash('acp_modules'),
516                'U_DISABLE'            => $url . '&amp;action=disable&amp;hash=' . generate_link_hash('acp_modules'))
517            );
518        }
519        $db->sql_freeresult($result);
520
521        // Quick adding module
522        $module_infos = $module_manager->get_module_infos($this->module_class);
523
524        // Build quick options
525        $s_install_options = '';
526        foreach ($module_infos as $option => $values)
527        {
528            // Name options
529            $s_install_options .= '<optgroup label="' . $user->lang($values['title']) . ' [' . $option . ']">';
530
531            // Build module modes
532            foreach ($values['modes'] as $m_mode => $m_values)
533            {
534                $s_install_options .= '<option value="' . $option . '::' . $m_mode . '">&nbsp; &nbsp;' . $user->lang($m_values['title']) . '</option>';
535            }
536
537            $s_install_options .= '</optgroup>';
538        }
539
540        $template->assign_vars(array(
541            'U_SEL_ACTION'        => $this->u_action,
542            'U_ACTION'            => $this->u_action . '&amp;parent_id=' . $this->parent_id,
543            'NAVIGATION'        => $navigation,
544            'MODULE_BOX'        => $module_box,
545            'PARENT_ID'            => $this->parent_id,
546            'S_INSTALL_OPTIONS'    => $s_install_options,
547            )
548        );
549    }
550
551    /**
552    * Simple version of jumpbox, just lists modules
553    */
554    function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false)
555    {
556        global $db, $user;
557
558        $sql = 'SELECT module_id, module_enabled, module_basename, parent_id, module_langname, left_id, right_id, module_auth
559            FROM ' . MODULES_TABLE . "
560            WHERE module_class = '" . $db->sql_escape($this->module_class) . "'
561            ORDER BY left_id ASC";
562        $result = $db->sql_query($sql);
563
564        $right = 0;
565        $padding_store = array('0' => '');
566        $module_list = $padding = '';
567
568        while ($row = $db->sql_fetchrow($result))
569        {
570            if ($row['left_id'] < $right)
571            {
572                $padding .= '&nbsp; &nbsp;';
573                $padding_store[$row['parent_id']] = $padding;
574            }
575            else if ($row['left_id'] > $right + 1)
576            {
577                $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
578            }
579
580            $right = $row['right_id'];
581
582            if (!$ignore_acl && $row['module_auth'])
583            {
584                // We use zero as the forum id to check - global setting.
585                if (!p_master::module_auth($row['module_auth'], 0))
586                {
587                    continue;
588                }
589            }
590
591            // ignore this module?
592            if ((is_array($ignore_id) && in_array($row['module_id'], $ignore_id)) || $row['module_id'] == $ignore_id)
593            {
594                continue;
595            }
596
597            // empty category
598            if (!$row['module_basename'] && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat)
599            {
600                continue;
601            }
602
603            // ignore non-category?
604            if ($row['module_basename'] && $ignore_noncat)
605            {
606                continue;
607            }
608
609            $selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : '');
610
611            $langname = $user->lang($row['module_langname']);
612            $module_list .= '<option value="' . $row['module_id'] . '"' . $selected . ((!$row['module_enabled']) ? ' class="disabled"' : '') . '>' . $padding . $langname . '</option>';
613        }
614        $db->sql_freeresult($result);
615
616        unset($padding_store);
617
618        return $module_list;
619    }
620}