diff options
| author | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
|---|---|---|
| committer | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
| commit | 4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch) | |
| tree | 5c07151ae61276d334e88f6309c30d439a85c12e /app/controllers/admin | |
| parent | da0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff) | |
| parent | 97a188592c679890a25c37ab78463add76a52ff7 (diff) | |
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'app/controllers/admin')
| -rw-r--r-- | app/controllers/admin/additional.php | 2 | ||||
| -rw-r--r-- | app/controllers/admin/api.php | 210 | ||||
| -rw-r--r-- | app/controllers/admin/cache.php | 11 | ||||
| -rw-r--r-- | app/controllers/admin/courseplanning.php | 2 | ||||
| -rw-r--r-- | app/controllers/admin/courses.php | 322 | ||||
| -rw-r--r-- | app/controllers/admin/cronjobs/schedules.php | 39 | ||||
| -rw-r--r-- | app/controllers/admin/datafields.php | 10 | ||||
| -rw-r--r-- | app/controllers/admin/domain.php | 2 | ||||
| -rw-r--r-- | app/controllers/admin/extern.php | 16 | ||||
| -rw-r--r-- | app/controllers/admin/install.php | 4 | ||||
| -rw-r--r-- | app/controllers/admin/lockrules.php | 4 | ||||
| -rw-r--r-- | app/controllers/admin/plugin.php | 36 | ||||
| -rw-r--r-- | app/controllers/admin/sem_classes.php | 2 | ||||
| -rw-r--r-- | app/controllers/admin/tree.php | 15 | ||||
| -rw-r--r-- | app/controllers/admin/user.php | 10 |
15 files changed, 192 insertions, 493 deletions
diff --git a/app/controllers/admin/additional.php b/app/controllers/admin/additional.php index a98da20..6f8f08c 100644 --- a/app/controllers/admin/additional.php +++ b/app/controllers/admin/additional.php @@ -30,6 +30,8 @@ class Admin_AdditionalController extends AuthenticatedController throw new AccessDeniedException(_("Sie haben keine Berechtigung diese " . "Veranstaltung zu verändern.")); } + + Sidebar::get()->addWidget(new CourseManagementSelectWidget()); } /** diff --git a/app/controllers/admin/api.php b/app/controllers/admin/api.php deleted file mode 100644 index 96adb65..0000000 --- a/app/controllers/admin/api.php +++ /dev/null @@ -1,210 +0,0 @@ -<?php -/** - * - **/ -class Admin_ApiController extends AuthenticatedController -{ - /** - * - **/ - public function before_filter(&$action, &$args) - { - parent::before_filter($action, $args); - - require_once 'lib/bootstrap-api.php'; - - $GLOBALS['perm']->check('root'); - - Navigation::activateItem('/admin/config/api'); - PageLayout::setTitle(_('API Verwaltung')); - - $this->types = [ - 'website' => _('Website'), - 'desktop' => _('Herkömmliches Desktopprogramm'), - 'mobile' => _('Mobile App') - ]; - - // Sidebar - $views = new ViewsWidget(); - $views->addLink(_('Registrierte Applikationen'), - $this->url_for('admin/api')) - ->setActive($action === 'index'); - $views->addLink(_('Globale Zugriffseinstellungen'), - $this->url_for('admin/api/permissions')) - ->setActive($action == 'permissions'); - $views->addLink(_('Konfiguration'), - $this->url_for('admin/api/config')) - ->setActive($action == 'config'); - Sidebar::get()->addWidget($views); - - $actions = new ActionsWidget(); - $actions->addLink(_('Neue Applikation registrieren'), - $this->url_for('admin/api/edit'), - Icon::create('add', 'clickable')) - ->asDialog(); - Sidebar::get()->addWidget($actions); - } - - /** - * - **/ - public function index_action() - { - $this->consumers = RESTAPI\Consumer\Base::findAll(); - $this->routes = RESTAPI\Router::getInstance()->getRoutes(true); - } - - /** - * - **/ - public function render_keys($id) - { - $consumer = RESTAPI\Consumer\Base::find($id); - - return [ - 'Consumer Key = ' . $consumer->auth_key, - 'Consumer Secret = ' . $consumer->auth_secret, - ]; - } - - /** - * - **/ - public function keys_action($id) - { - $details = $this->render_keys($id); - - if (Request::isXhr()) { - $this->render_text(implode('<br>', $details)); - } else { - PageLayout::postMessage(MessageBox::info(_('Die Schlüssel in den Details dieser Meldung sollten vertraulich behandelt werden!'), $details, true)); - $this->redirect('admin/api/#' . $id); - } - } - - /** - * - **/ - public function edit_action($id = null) - { - $consumer = $id - ? RESTAPI\Consumer\Base::find($id) - : RESTAPI\Consumer\Base::create(Request::option('consumer_type') ?: 'oauth'); - - if (Request::submitted('store')) { - $errors = []; - - $consumer->active = (bool) Request::int('active'); - $consumer->title = Request::get('title'); - $consumer->contact = Request::get('contact'); - $consumer->email = Request::get('email'); - $consumer->callback = Request::get('callback'); - $consumer->url = Request::get('url'); - $consumer->type = Request::get('type') ?: null; - $consumer->commercial = Request::int('commercial'); - $consumer->notes = Request::get('notes'); - $consumer->description = Request::get('description'); - - if (!empty($errors)) { - $message = MessageBox::error(_('Folgende Fehler sind aufgetreten:'), $errors); - PageLayout::postMessage($message); - return; - } - - $consumer->store(); - - if ($id) { - $message = MessageBox::success(_('Die Applikation wurde erfolgreich gespeichert.')); - } else { - $details = $this->render_keys($consumer->id); - $message = MessageBox::success(_('Die Applikation wurde erfolgreich erstellt, die Schlüssel finden Sie in den Details dieser Meldung.'), $details, true); - } - PageLayout::postMessage($message); - $this->redirect('admin/api/index#' . $consumer->id); - return; - } - - $this->consumer = $consumer; - $this->id = $id; - } - - /** - * - **/ - public function toggle_action($id, $state = null) - { - $consumer = RESTAPI\Consumer\Base::find($id); - - $consumer->active = $state === null ? !$consumer->active : ($state === 'on'); - $consumer->store(); - - $message = $state - ? _('Die Applikation wurde erfolgreich aktiviert.') - : _('Die Applikation wurde erfolgreich deaktiviert.'); - - PageLayout::postMessage(MessageBox::success($message)); - $this->redirect('admin/api/#' . $consumer->id); - } - - /** - * - **/ - public function delete_action($id) - { - if (!Request::isPost()) { - throw new MethodNotAllowedException(); - } - if ($consumer = RESTAPI\Consumer\Base::find($id)) { - $consumer->delete(); - - PageLayout::postSuccess(_('Die Applikation wurde erfolgreich gelöscht.')); - } - $this->redirect('admin/api'); - } - - /** - * - **/ - public function permissions_action($consumer_id = null) - { - if (Request::submitted('store')) { - $perms = Request::getArray('permission'); - $permissions = RESTAPI\ConsumerPermissions::get($consumer_id ?: 'global'); - - foreach ($perms as $route => $methods) { - foreach ($methods as $method => $granted) { - $permissions->set(urldecode($route), urldecode($method), (bool)$granted, true); - } - } - - $permissions->store(); - - PageLayout::postMessage(MessageBox::success(_('Die Zugriffsberechtigungen wurden erfolgreich gespeichert'))); - $this->redirect($consumer_id ? 'admin/api' : 'admin/api/permissions'); - return; - } - - $title = $consumer_id ? _('Zugriffsberechtigungen') : _('Globale Zugriffsberechtigungen'); - $title .= ' - ' . PageLayout::getTitle(); - PageLayout::setTitle($title); - - $this->consumer_id = $consumer_id; - $this->router = RESTAPI\Router::getInstance(); - $this->routes = $this->router->getRoutes(true, false); - $this->permissions = RESTAPI\ConsumerPermissions::get($consumer_id ?: 'global'); - $this->global = $consumer_id ? RESTAPI\ConsumerPermissions::get('global') : false; - } - - public function config_action() - { - $this->config = Config::get(); - - if (Request::isPost()) { - $this->config->store('API_ENABLED', Request::int('active', 0)); - $this->config->store('API_OAUTH_AUTH_PLUGIN', Request::option('auth')); - - PageLayout::postMessage(MessageBox::success(_('Die Einstellungen wurden gespeichert.'))); - $this->redirect('admin/api/config'); - } - } -} diff --git a/app/controllers/admin/cache.php b/app/controllers/admin/cache.php index 329aab7..c016af5 100644 --- a/app/controllers/admin/cache.php +++ b/app/controllers/admin/cache.php @@ -81,11 +81,10 @@ class Admin_CacheController extends AuthenticatedController /** * Fetches necessary configuration for given cache type. - * - * @param string $className */ - public function get_config_action($className) + public function get_config_action() { + $className = Request::get('cache'); $type = CacheType::findOneByClass_name($className); $this->render_json($type->class_name::getConfig()); @@ -111,7 +110,7 @@ class Admin_CacheController extends AuthenticatedController // Store settings to global config. if (Config::get()->store('SYSTEMCACHE', $settings)) { PageLayout::postSuccess(_('Die Einstellungen wurden gespeichert.')); - StudipCacheFactory::unconfigure(); + \Studip\Cache\Factory::unconfigure(); } $this->relocate('admin/cache/settings'); @@ -122,7 +121,7 @@ class Admin_CacheController extends AuthenticatedController */ public function flush_action() { - $cache = StudipCacheFactory::getCache(); + $cache = \Studip\Cache\Factory::getCache(); $cache->flush(); PageLayout::postSuccess(_('Die Inhalte des Caches wurden gelöscht.')); @@ -135,7 +134,7 @@ class Admin_CacheController extends AuthenticatedController */ public function stats_action() { - $cache = StudipCacheFactory::getCache(); + $cache = \Studip\Cache\Factory::getCache(); $this->stats = $cache->getStats(); } diff --git a/app/controllers/admin/courseplanning.php b/app/controllers/admin/courseplanning.php index b8971e2..44b372d 100644 --- a/app/controllers/admin/courseplanning.php +++ b/app/controllers/admin/courseplanning.php @@ -82,7 +82,7 @@ class Admin_CourseplanningController extends AuthenticatedController foreach ($this->events as $event) { $start_date_time = explode('T', $event['start']); $time_elements = explode(':', $start_date_time[1]); - if (!$event['comform'] || $time_elements[0] % 2) { + if (!$event['conform'] || $time_elements[0] % 2) { Sidebar::get()->getWidget('actions')->addLink( _('Veranstaltungen außerhalb des Rasters'), $this->nonconformURL(), diff --git a/app/controllers/admin/courses.php b/app/controllers/admin/courses.php index 6f9312d..5f60442 100644 --- a/app/controllers/admin/courses.php +++ b/app/controllers/admin/courses.php @@ -22,6 +22,7 @@ * @category Stud.IP * @since 3.1 */ + require_once 'lib/meine_seminare_func.inc.php'; require_once 'lib/object.inc.php'; require_once 'lib/archiv.inc.php'; //for lastActivity in getCourses() method @@ -293,7 +294,7 @@ class Admin_CoursesController extends AuthenticatedController PageLayout::setTitle(_('Verwaltung von Veranstaltungen und Einrichtungen')); // Add admission functions. PageLayout::addScript('studip-admission.js'); - $this->max_show_courses = 500; + $this->max_show_courses = Config::get()->MAX_SHOW_ADMIN_COURSES; } /** @@ -322,6 +323,9 @@ class Admin_CoursesController extends AuthenticatedController $institut_id = $configuration->MY_INSTITUTES_DEFAULT && $configuration->MY_INSTITUTES_DEFAULT !== 'all' ? $configuration->MY_INSTITUTES_DEFAULT : null; + if ($configuration->MY_INSTITUTES_INCLUDE_CHILDREN) { + $institut_id .= '_withinst'; + } $filters = array_merge( array_merge(...PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'getFilters')), @@ -375,14 +379,14 @@ class Admin_CoursesController extends AuthenticatedController } PluginEngine::sendMessage(AdminCourseWidgetPlugin::class, 'applyFilters', $filter); - $count = $filter->countCourses(); - if ($count > $this->max_show_courses && !Request::submitted('without_limit')) { - $this->render_json([ - 'count' => $count - ]); + try { + $courses = $filter->fetchCourses( + Request::bool('without_limit') ? null: $this->max_show_courses + ); + } catch (OverflowException $e) { + $this->render_json(['count' => (int) $e->getMessage()]); return; } - $courses = AdminCourseFilter::get()->getCourses(); $data = [ 'data' => [] @@ -417,7 +421,7 @@ class Admin_CoursesController extends AuthenticatedController } } } - $tf = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH'] . '/app/views'); + $tf = new Flexi\Factory($GLOBALS['STUDIP_BASE_PATH'] . '/app/views'); switch ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA) { case 1: case 2: @@ -487,12 +491,12 @@ class Admin_CoursesController extends AuthenticatedController ]); break; default: - foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) { + foreach (PluginManager::getInstance()->getPlugins(AdminCourseAction::class) as $plugin) { if ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA === get_class($plugin)) { $multimode = $plugin->useMultimode(); if ($multimode) { $data['buttons_top'] = '<label>'._('Alle auswählen').'<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>'; - if ($multimode instanceof Flexi_Template) { + if ($multimode instanceof Flex\Template) { $data['buttons_bottom'] = $multimode->render(); } elseif ($multimode instanceof \Studip\Button) { $data['buttons_bottom'] = (string) $multimode; @@ -531,14 +535,60 @@ class Admin_CoursesController extends AuthenticatedController 'institut_id' => 'MY_INSTITUTES_DEFAULT', ]; + if (!empty($filters['institut_id'])) { + $config->store( + 'MY_INSTITUTES_INCLUDE_CHILDREN', + str_contains($filters['institut_id'], '_') ? 1 : 0 + ); + if ($config->MY_INSTITUTES_INCLUDE_CHILDREN) { + $filters['institut_id'] = substr($filters['institut_id'], 0, strpos($filters['institut_id'], '_')); + } + } + foreach ($mapping as $key => $field) { if (isset($filters[$key])) { $config->store($field, $filters[$key]); } - unset($filters[$key]); } + if ($config->ADMIN_COURSES_TEACHERFILTER) { + if (!$config->MY_INSTITUTES_DEFAULT) { + $config->delete('ADMIN_COURSES_TEACHERFILTER'); + } else { + $include_children = $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN ? ' OR Institute.fakultaets_id = :institut_id ' : ''; + + $exists = InstituteMember::countBySQL("INNER JOIN `Institute` USING (`Institut_id`) WHERE `user_inst`.`user_id` = :user_id AND (`Institute`.`Institut_id` = :institut_id $include_children) AND `user_inst`.`inst_perms` = 'dozent' ", [ + 'user_id' => $config->ADMIN_COURSES_TEACHERFILTER, + 'institut_id' => $config->MY_INSTITUTES_DEFAULT + ]) > 0; + if (!$exists) { + $config->delete('ADMIN_COURSES_TEACHERFILTER'); + } + } + } + if ($config->MY_COURSES_SELECTED_STGTEIL) { + if (!$config->MY_INSTITUTES_DEFAULT) { + $config->delete('MY_COURSES_SELECTED_STGTEIL'); + } else { + $statement = DBManager::get()->prepare(" + SELECT 1 + FROM `mvv_stg_stgteil` + INNER JOIN `mvv_studiengang` ON (`mvv_stg_stgteil`.`studiengang_id` = `mvv_studiengang`.`studiengang_id`) + WHERE `mvv_studiengang`.`institut_id` = :institut_id + AND `mvv_stg_stgteil`.`stgteil_id` = :stgteil_id + "); + $statement->execute([ + 'institut_id' => $config->MY_INSTITUTES_DEFAULT, + 'stgteil_id' => $config->MY_COURSES_SELECTED_STGTEIL + ]); + $exists = (bool) $statement->fetch(PDO::FETCH_COLUMN); + if (!$exists) { + $config->delete('MY_COURSES_SELECTED_STGTEIL'); + } + } + } + // Datafield filters $activeSidebarElements = $this->getActiveElements(); @@ -576,19 +626,19 @@ class Admin_CoursesController extends AuthenticatedController if (in_array('name', $activated_fields)) { $params = tooltip2(_('Veranstaltungsdetails anzeigen')); $params['style'] = 'cursor: pointer'; - $d['name'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">' + $d['name'] = '<a href="'.URLHelper::getLink('dispatch.php/course/basicdata/view', ['cid' => $course->id]).'">' . htmlReady($course->name) .'</a> ' .'<a href="'.URLHelper::getLink('dispatch.php/course/details/index/'. $course->id).'" data-dialog><button class="undecorated">'.Icon::create('info-circle', Icon::ROLE_INACTIVE)->asImg($params).'</button></a> ' .(!$course->visible ? _('(versteckt)') : ''); } if (in_array('number', $activated_fields)) { - $d['number'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">' + $d['number'] = '<a href="'.URLHelper::getLink('dispatch.php/course/basicdata/view', ['cid' => $course->id]).'">' .$course->veranstaltungsnummer .'</a>'; } if (in_array('avatar', $activated_fields)) { - $d['avatar'] = '<a href="'.URLHelper::getLink('seminar_main.php', ['auswahl' => $course->id]).'">' + $d['avatar'] = '<a href="'.URLHelper::getLink('dispatch.php/course/basicdata/view', ['cid' => $course->id]).'">' .CourseAvatar::getAvatar($course->getId())->getImageTag(Avatar::SMALL, ['title' => $course->name]) ."</a>"; } @@ -604,6 +654,7 @@ class Admin_CoursesController extends AuthenticatedController } if (in_array('semester', $activated_fields)) { $d['semester'] = $course->semester_text; + $d['semester_sort'] = $course->start_semester ? $course->start_semester->beginn : 0; } if (in_array('institute', $activated_fields)) { $d['institute'] = $course->home_institut ? $course->home_institut->name : $course->institute; @@ -620,7 +671,7 @@ class Admin_CoursesController extends AuthenticatedController } if (in_array('members', $activated_fields)) { $d['members'] = '<a href="'.URLHelper::getLink('dispatch.php/course/members', ['cid' => $course->id]).'">' - .$course->getNumParticipants() + .$course->countMembersWithStatus('user autor') .'</a>'; } if (in_array('waiting', $activated_fields)) { @@ -663,15 +714,18 @@ class Admin_CoursesController extends AuthenticatedController $d['last_activity_raw'] = $last_activity; } - foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) { + foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) { foreach ($plugin->adminAvailableContents() as $index => $label) { if (in_array($plugin->getPluginId() . '_' . $index, $activated_fields)) { $content = $plugin->adminAreaGetCourseContent($course, $index); - $d[$plugin->getPluginId()."_".$index] = $content instanceof Flexi_Template ? $content->render() : $content; + if ($content instanceof Flexi\Template) { + $content = $content->render(); + } + $d[$plugin->getPluginId()."_".$index] = $content; } } } - $tf = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH'].'/app/views'); + $tf = new Flexi\Factory($GLOBALS['STUDIP_BASE_PATH'].'/app/views'); switch ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA) { case 1: @@ -789,10 +843,13 @@ class Admin_CoursesController extends AuthenticatedController $d['action'] = $template->render(); break; default: - foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) { + foreach (PluginManager::getInstance()->getPlugins(AdminCourseAction::class) as $plugin) { if ($GLOBALS['user']->cfg->MY_COURSES_ACTION_AREA === get_class($plugin)) { $output = $plugin->getAdminCourseActionTemplate($course->getId()); - $d['action'] = $output instanceof Flexi_Template ? $output->render() : (string) $output; + if ($output instanceof Flexi\Template) { + $output = $output->render(); + } + $d['action'] = (string) $output; break; } } @@ -981,14 +1038,14 @@ class Admin_CoursesController extends AuthenticatedController $row['institute'] = $course->home_institut ? (string) $course->home_institut['name'] : $course['institut_id']; } - foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) { + foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) { foreach ($plugin->adminAvailableContents() as $index => $label) { if (in_array($plugin->getPluginId() . "_" . $index, $filter_config)) { $content = $plugin->adminAreaGetCourseContent($course, $index); - $row[$plugin->getPluginId() . "_" . $index] = strip_tags(is_a($content, 'Flexi_Template') - ? $content->render() - : $content - ); + if ($content instanceof Flexi\Template) { + $content = $content->render(); + } + $row[$plugin->getPluginId() . "_" . $index] = strip_tags($content); } } } @@ -1000,7 +1057,7 @@ class Admin_CoursesController extends AuthenticatedController foreach ($filter_config as $index) { $captions[$index] = $view_filters[$index]; } - foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) { + foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) { foreach ($plugin->adminAvailableContents() as $index => $label) { if (in_array($plugin->getPluginId() . "_" . $index, $filter_config)) { $captions[$plugin->getPluginId() . "_" . $index] = $label; @@ -1398,7 +1455,7 @@ class Admin_CoursesController extends AuthenticatedController ksort($actions); - foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) { + foreach (PluginManager::getInstance()->getPlugins(AdminCourseAction::class) as $plugin) { $actions[get_class($plugin)] = [ 'name' => $plugin->getPluginName(), 'title' => $plugin->getPluginName(), @@ -1438,7 +1495,7 @@ class Admin_CoursesController extends AuthenticatedController 'contents' => _('Inhalt'), 'last_activity' => _('Letzte Aktivität'), ]; - foreach (PluginManager::getInstance()->getPlugins('AdminCourseContents') as $plugin) { + foreach (PluginManager::getInstance()->getPlugins(AdminCourseContents::class) as $plugin) { foreach ($plugin->adminAvailableContents() as $index => $label) { $views[$plugin->getPluginId() . "_" . $index] = $label; } @@ -1446,169 +1503,6 @@ class Admin_CoursesController extends AuthenticatedController return $views; } - /** - * Returns all courses matching set criteria. - * - * @param array $params Additional parameters - * @param bool $display_all : boolean should we show all courses or check for a limit of 500 courses? - * @return array of courses - */ - private function getCourses($params = [], $display_all = false) - { - // Init - if ($GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === "all") { - $inst = new SimpleCollection($this->insts); - $inst->filter(function ($a) use (&$inst_ids) { - $inst_ids[] = $a->Institut_id; - }); - } else { - //We must check, if the institute ID belongs to a faculty - //and has the string _i appended to it. - //In that case we must display the courses of the faculty - //and all its institutes. - //Otherwise we just display the courses of the faculty. - - $inst_id = $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT; - - $institut = new Institute($inst_id); - - if (!$institut->isFaculty() || $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN) { - // If the institute is not a faculty or the child insts are included, - // pick the institute IDs of the faculty/institute and of all sub-institutes. - $inst_ids[] = $inst_id; - if ($institut->isFaculty()) { - foreach ($institut->sub_institutes->pluck('Institut_id') as $institut_id) { - $inst_ids[] = $institut_id; - } - } - } else { - // If the institute is a faculty and the child insts are not included, - // pick only the institute id of the faculty: - $inst_ids[] = $inst_id; - } - } - - $active_elements = $this->getActiveElements(); - - $filter = AdminCourseFilter::get(true); - - if ($params['datafields']) { - foreach ($params['datafields'] as $field_id => $value) { - $datafield = DataField::find($field_id); - if ($datafield) { - //enable filtering by datafield values: - //and use the where-clause for each datafield: - $filter->settings['query']['joins']['de_'.$field_id] = [ - 'table' => "datafields_entries", - 'join' => "LEFT JOIN", - 'on' => "seminare.seminar_id = de_".$field_id.".range_id" - ]; - $filter->where("(de_".$field_id.".datafield_id = :fieldId_".$field_id." " - . "AND de_".$field_id.".content = :fieldValue_".$field_id.") " - . ($datafield['default_value'] == $value ? " OR (de_".$field_id.".content IS NULL)" : "")." ", - [ - 'fieldId_'.$field_id => $field_id, - 'fieldValue_'.$field_id => $value - ] - ); - } - } - } - - $filter->where("sem_classes.studygroup_mode = '0'"); - - // Get only children of given course - if (!empty($params['parent_course'])) { - $filter->where("parent_course = :parent", - [ - 'parent' => $params['parent_course'] - ] - ); - } - - if ($active_elements['semester'] && is_object($this->semester)) { - $filter->filterBySemester($this->semester->getId()); - } - if ($active_elements['courseType'] && $params['typeFilter'] && $params['typeFilter'] !== "all") { - $parts = explode('_', $params['typeFilter']); - $class_filter = $parts[0]; - $type_filter = $parts[1] ?? null; - if (!$type_filter && !empty($GLOBALS['SEM_CLASS'][$class_filter])) { - $type_filter = array_keys($GLOBALS['SEM_CLASS'][$class_filter]->getSemTypes()); - } - $filter->filterByType($type_filter); - } - if ($active_elements['search'] && $GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT) { - $filter->filterBySearchString($GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT); - } - if ($active_elements['teacher'] && $GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER && ($GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER !== "all")) { - $filter->filterByDozent($GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER); - } - if ($active_elements['institute']) { - $filter->filterByInstitute($inst_ids); - } - if ($GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL && $GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL !== 'all') { - $filter->filterByStgTeil($GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL); - } - if ($params['sortby'] === "status") { - $filter->orderBy(sprintf('sem_classes.name %s, sem_types.name %s, VeranstaltungsNummer %s', $params['sortFlag'], $params['sortFlag'], $params['sortFlag']), $params['sortFlag']); - } elseif ($params['sortby'] === 'institute') { - $filter->orderBy('Institute.Name', $params['sortFlag']); - } elseif ($params['sortby']) { - $filter->orderBy($params['sortby'], $params['sortFlag']); - } - $filter->storeSettings(); - $this->count_courses = $filter->countCourses(); - if ($this->count_courses && ($this->count_courses <= $filter->max_show_courses || $display_all)) { - $courses = $filter->getCourses(); - } else { - return []; - } - - $seminars = []; - if (!empty($courses)) { - foreach ($courses as $seminar_id => $seminar) { - $seminars[$seminar_id] = $seminar[0]; - $seminars[$seminar_id]['seminar_id'] = $seminar_id; - $seminars[$seminar_id]['obj_type'] = 'sem'; - $dozenten = $this->getTeacher($seminar_id); - $seminars[$seminar_id]['dozenten'] = $dozenten; - - if (in_array('contents', $params['view_filter'])) { - $tools = new SimpleCollection(ToolActivation::findbyRange_id($seminar_id, "ORDER BY position")); - $visit_data = get_objects_visits([$seminar_id], 0, null, null, $tools->pluck('plugin_id')); - $seminars[$seminar_id]['visitdate'] = $visit_data[$seminar_id][0]['visitdate']; - $seminars[$seminar_id]['last_visitdate'] = $visit_data[$seminar_id][0]['last_visitdate']; - $seminars[$seminar_id]['tools'] = $tools; - $seminars[$seminar_id]['navigation'] = MyRealmModel::getAdditionalNavigations( - $seminar_id, - $seminars[$seminar_id], - $seminars[$seminar_id]['sem_class'] ?? null, - $GLOBALS['user']->id, - $visit_data[$seminar_id] - ); - } - //add last activity column: - if (in_array('last_activity', $params['view_filter'])) { - $seminars[$seminar_id]['last_activity'] = lastActivity($seminar_id); - } - if ((int)$this->selected_action === 17) { - $seminars[$seminar_id]['admission_locked'] = false; - if ($seminar[0]['course_set']) { - $set = new CourseSet($seminar[0]['course_set']); - if (!is_null($set) && $set->hasAdmissionRule('LockedAdmission')) { - $seminars[$seminar_id]['admission_locked'] = 'locked'; - } else { - $seminars[$seminar_id]['admission_locked'] = 'disable'; - } - unset($set); - } - } - } - } - - return $seminars; - } /** * Returns the teacher for a given cours @@ -1650,6 +1544,7 @@ class Admin_CoursesController extends AuthenticatedController $institut['Institut_id'], (!$institut['is_fak'] ? ' ' : '') . $institut['Name'], $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id'] + && !$GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN ); //check if the institute is a faculty. @@ -1662,7 +1557,8 @@ class Admin_CoursesController extends AuthenticatedController new SelectElement( $institut['Institut_id'] . '_withinst', //_withinst = with institutes ' ' . $institut['Name'] . ' +' . _('Institute'), - ($GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id'] && $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN) + $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === $institut['Institut_id'] + && $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN ); } } @@ -1695,6 +1591,9 @@ class Admin_CoursesController extends AuthenticatedController private function getStgteilSelector($institut_id = null) { $institut_id = $institut_id ?: $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT; + if (str_contains($institut_id, '_')) { + $institut_id = substr($institut_id, 0, strpos($institut_id, '_')); + } $stgteile = StudiengangTeil::getAllEnriched('fach_name', 'ASC', ['mvv_fach_inst.institut_id' => $institut_id]); $list = []; if (!$institut_id || $institut_id === 'all') { @@ -1782,27 +1681,42 @@ class Admin_CoursesController extends AuthenticatedController */ private function getTeacherWidget($institut_id = null) { - $institut_id = $institut_id ?: $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT; - $teachers = DBManager::get()->fetchAll(" + if ($institut_id) { + if (str_contains($institut_id, '_')) { + $institut_id = substr($institut_id, 0, strpos($institut_id, '_')); + $GLOBALS['user']->cfg->store('MY_INSTITUTES_INCLUDE_CHILDREN', 1); + } else { + $GLOBALS['user']->cfg->store('MY_INSTITUTES_INCLUDE_CHILDREN', 0); + } + } else { + $institut_id = $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT; + } + + $teachers = []; + $include_children = $GLOBALS['user']->cfg->MY_INSTITUTES_INCLUDE_CHILDREN ? ' OR Institute.fakultaets_id = :institut_id ' : ''; + + if ($institut_id) { + $teachers = DBManager::get()->fetchAll(" SELECT auth_user_md5.*, user_info.* FROM auth_user_md5 LEFT JOIN user_info ON (auth_user_md5.user_id = user_info.user_id) INNER JOIN user_inst ON (user_inst.user_id = auth_user_md5.user_id) INNER JOIN Institute ON (Institute.Institut_id = user_inst.Institut_id) - WHERE (Institute.Institut_id = :institut_id OR Institute.fakultaets_id = :institut_id) - AND auth_user_md5.perms = 'dozent' + WHERE (Institute.Institut_id = :institut_id $include_children) + AND user_inst.inst_perms = 'dozent' + GROUP BY auth_user_md5.user_id ORDER BY auth_user_md5.Nachname ASC, auth_user_md5.Vorname ASC ", [ 'institut_id' => $institut_id ], - function ($data) { - $ret['user_id'] = $data['user_id']; - unset($data['user_id']); - $ret['fullname'] = User::build($data)->getFullName("full_rev"); - return $ret; - } - ); - + function ($data) { + $ret['user_id'] = $data['user_id']; + unset($data['user_id']); + $ret['fullname'] = User::build($data)->getFullName("full_rev"); + return $ret; + } + ); + } $list = []; if (!$institut_id || $institut_id === 'all') { diff --git a/app/controllers/admin/cronjobs/schedules.php b/app/controllers/admin/cronjobs/schedules.php index 294d78d..929ae29 100644 --- a/app/controllers/admin/cronjobs/schedules.php +++ b/app/controllers/admin/cronjobs/schedules.php @@ -29,7 +29,7 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController if (empty($_SESSION['cronjob-filter'])) { $_SESSION['cronjob-filter'] = [ 'where' => '1', - 'values' => array_fill_keys(['type', 'status', 'task_id'], null), + 'values' => array_fill_keys(['status', 'task_id'], null), ]; } @@ -102,9 +102,6 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController $filter = array_filter(Request::optionArray('filter')); $conditions = []; - if (!empty($filter['type'])) { - $conditions[] = "type = " . DBManager::get()->quote($filter['type']); - } if (!empty($filter['status'])) { $active = (int)($filter['status'] === 'active'); $conditions[] = "active = " . DBManager::get()->quote($active); @@ -130,7 +127,6 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController if (Request::submitted('store')) { $parameters = Request::getArray('parameters'); - $schedule->priority = Request::option('priority', 'normal'); $schedule->title = Request::get('title'); $schedule->description = Request::get('description'); $schedule->active = Request::int('active', 0); @@ -138,27 +134,20 @@ class Admin_Cronjobs_SchedulesController extends AuthenticatedController $schedule->task_id = Request::option('task_id'); } $schedule->parameters = $parameters[$schedule->task_id]; - $schedule->type = Request::option('type') === 'once' - ? 'once' - : 'periodic'; - - if ($schedule->type === 'once') { - $temp = Request::getArray('once'); - $schedule->next_execution = strtotime($temp['date'] . ' ' . $temp['time']); - } else { - $temp = Request::getArray('periodic'); - $schedule->minute = $this->extractCronItem($temp['minute']); - $schedule->hour = $this->extractCronItem($temp['hour']); - $schedule->day = $this->extractCronItem($temp['day']); - $schedule->month = $this->extractCronItem($temp['month']); - $schedule->day_of_week = mb_strlen($temp['day_of_week']['value']) - ? (int) $temp['day_of_week']['value'] - : null; - - if ($schedule->active) { - $schedule->next_execution = $schedule->calculateNextExecution(); - } + + $temp = Request::getArray('periodic'); + $schedule->minute = $this->extractCronItem($temp['minute']); + $schedule->hour = $this->extractCronItem($temp['hour']); + $schedule->day = $this->extractCronItem($temp['day']); + $schedule->month = $this->extractCronItem($temp['month']); + $schedule->day_of_week = mb_strlen($temp['day_of_week']['value']) + ? (int) $temp['day_of_week']['value'] + : null; + + if ($schedule->active) { + $schedule->next_execution = $schedule->calculateNextExecution(); } + $schedule->store(); PageLayout::postSuccess(_('Die Änderungen wurden gespeichert.')); diff --git a/app/controllers/admin/datafields.php b/app/controllers/admin/datafields.php index bf390c9..6019a13 100644 --- a/app/controllers/admin/datafields.php +++ b/app/controllers/admin/datafields.php @@ -94,15 +94,17 @@ class Admin_DatafieldsController extends AuthenticatedController if (Request::submitted('uebernehmen')) { if (Request::get('datafield_name')) { - $datafield->name = Request::i18n('datafield_name'); - if ($datafield->object_type === 'moduldeskriptor' - || $datafield->object_type === 'modulteildeskriptor') { + $datafield->name = Request::i18n('datafield_name'); + if ( + $datafield->object_type === 'moduldeskriptor' + || $datafield->object_type === 'modulteildeskriptor' + ) { $object_class = implode(',', Request::getArray('object_class')); $datafield->object_class = (trim($object_class) && $object_class != 'NULL') ? $object_class : null; } elseif ($datafield->object_type === 'studycourse') { $datafield->object_class = trim(Request::option('object_class', 'all_settings')); } else { - $datafield->object_class = array_sum(Request::getArray('object_class')) ?: null; + $datafield->object_class = array_sum(Request::intArray('object_class')) ?: null; } $datafield->edit_perms = Request::get('edit_perms'); $datafield->view_perms = Request::get('visibility_perms'); diff --git a/app/controllers/admin/domain.php b/app/controllers/admin/domain.php index e4bb9c8..37ab11f 100644 --- a/app/controllers/admin/domain.php +++ b/app/controllers/admin/domain.php @@ -70,7 +70,7 @@ class Admin_DomainController extends AuthenticatedController { foreach ($args as $arg) { if ($arg && !preg_match('/' . UserDomain::REGEXP . '/', $arg)) { - throw new Trails_Exception(400); + throw new Trails\Exception(400); } } diff --git a/app/controllers/admin/extern.php b/app/controllers/admin/extern.php index 41833b1..732b586 100644 --- a/app/controllers/admin/extern.php +++ b/app/controllers/admin/extern.php @@ -66,8 +66,8 @@ class Admin_ExternController extends AuthenticatedController ExternPageConfig::findEachBySQL( function ($c) use (&$configs, &$count_not_migrated) { $configs[$c->type][] = $c; - if (isset($c->conf['not_fixed_after_migration'])) { - $count_not_migrated++; + if (isset($c->conf['not_fixed_after_migration'])) { + $count_not_migrated++; } }, "range_id = ?", [$this->range] @@ -165,7 +165,7 @@ class Admin_ExternController extends AuthenticatedController if ($this->page->page_config->isNew()) { PageLayout::postSuccess(sprintf( _('Eine neue externe Seite "%$1s" vom Typ %$2s wurde angelegt.'), - htmlReady($this->page->name), + htmlReady($this->page->name), htmlReady($this->page->type) )); } else { @@ -259,7 +259,11 @@ class Admin_ExternController extends AuthenticatedController */ public function info_action(string $config_id) { - $this->page = ExternPage::get(ExternPageConfig::find($config_id)); + $config = ExternPageConfig::find($config_id); + if (!$config) { + throw new Exception('ExternPageConfig object not found!'); + } + $this->page = ExternPage::get($config); if ($this->page->author) { $this->author = '<a href="' . URLHelper::getLink('dispatch.php/profile', ['username' => $this->page->author->username]) @@ -364,7 +368,7 @@ class Admin_ExternController extends AuthenticatedController $config->author_id = $config->editor_id = $GLOBALS['user']->id; $config->store(); PageLayout::postSuccess( - sprintf(_('Die Konfiguration "%s" wurde erfolgreich importiert.'), + sprintf(_('Die Konfiguration "%s" wurde erfolgreich importiert.'), htmlReady($config->name) )); } @@ -436,7 +440,7 @@ class Admin_ExternController extends AuthenticatedController */ protected function fetchPlugins(bool $is_system): void { - $plugins = PluginEngine::getPlugins('ExternPagePlugin'); + $plugins = PluginEngine::getPlugins(ExternPagePlugin::class); foreach ($plugins as $plugin) { if ( $is_system === $plugin->isSystemPage() diff --git a/app/controllers/admin/install.php b/app/controllers/admin/install.php index 0054445..e45c281 100644 --- a/app/controllers/admin/install.php +++ b/app/controllers/admin/install.php @@ -1,7 +1,7 @@ <?php -require_once __DIR__ . '/../studip_controller_properties_trait.php'; +require_once __DIR__ . '/../../../lib/classes/StudipControllerPropertiesTrait.php'; -class Admin_InstallController extends Trails_Controller +class Admin_InstallController extends Trails\Controller { use StudipControllerPropertiesTrait; diff --git a/app/controllers/admin/lockrules.php b/app/controllers/admin/lockrules.php index 56879fe..202a2e9 100644 --- a/app/controllers/admin/lockrules.php +++ b/app/controllers/admin/lockrules.php @@ -164,7 +164,7 @@ class Admin_LockrulesController extends AuthenticatedController { $this->lock_rule = LockRule::find($lock_rule_id); if (!(!$this->lock_rule->isNew() && ($GLOBALS['perm']->have_perm('root') || $this->lock_rule->user_id === $GLOBALS['user']->id))) { - throw new Trails_Exception(403); + throw new Trails\Exception(403); } CSRFProtection::verifyUnsafeRequest(); if ($this->lock_rule->delete()) { @@ -186,4 +186,4 @@ class Admin_LockrulesController extends AuthenticatedController } return $this->lock_rule->store(); } -}
\ No newline at end of file +} diff --git a/app/controllers/admin/plugin.php b/app/controllers/admin/plugin.php index 903c45e..8a6935b 100644 --- a/app/controllers/admin/plugin.php +++ b/app/controllers/admin/plugin.php @@ -86,7 +86,7 @@ class Admin_PluginController extends AuthenticatedController * update information is available, an error message is set in * this controller and an empty array is returned. * - * @param array array of plugin meta data + * @param array $plugins array of plugin meta data */ private function get_update_info($plugins) { @@ -127,7 +127,6 @@ class Admin_PluginController extends AuthenticatedController } $plugin_manager = PluginManager::getInstance(); - $plugin_filter = Request::option('plugin_filter', ''); $plugins = $plugin_manager->getPluginInfos($this->plugin_filter); @@ -200,7 +199,6 @@ class Admin_PluginController extends AuthenticatedController _('Die Position von Plugin "%s" wurde verändert.'), $plugin['name'] ); - $changed = true; } } } @@ -344,7 +342,7 @@ class Admin_PluginController extends AuthenticatedController /** * Ask for confirmation from the user before deleting a plugin. * - * @param integer id of plugin to delete + * @param int $plugin_id id of plugin to delete */ public function ask_delete_action($plugin_id) { @@ -366,7 +364,7 @@ class Admin_PluginController extends AuthenticatedController /** * Completely delete a plugin from the system. * - * @param integer id of plugin to delete + * @param int $plugin_id id of plugin to delete */ public function delete_action($plugin_id) { @@ -390,7 +388,7 @@ class Admin_PluginController extends AuthenticatedController /** * Download a ZIP file containing the given plugin. * - * @param integer id of plugin to download + * @param int $plugin_id id of plugin to download */ public function download_action($plugin_id) { @@ -441,16 +439,16 @@ class Admin_PluginController extends AuthenticatedController $update_info = $this->plugin_admin->getUpdateInfo($plugins); $update = $this->flash['update']; - $update_status = []; - - // update each plugin in turn - foreach ($update as $id) { - if (isset($update_info[$id]['update'])) { - try { - $update_url = $update_info[$id]['update']['url']; - $this->plugin_admin->installPluginFromURL($update_url); - } catch (PluginInstallationException $ex) { - $update_errors[] = sprintf('%s: %s', $plugins[$id]['name'], $ex->getMessage()); + + if (!empty($update)) { // update each plugin in turn + foreach ($update as $id) { + if (isset($update_info[$id]['update'])) { + try { + $update_url = $update_info[$id]['update']['url']; + $this->plugin_admin->installPluginFromURL($update_url); + } catch (PluginInstallationException $ex) { + $update_errors[] = sprintf('%s: %s', $plugins[$id]['name'], $ex->getMessage()); + } } } } @@ -473,6 +471,8 @@ class Admin_PluginController extends AuthenticatedController /** * Show a page describing this plugin's meta data and description, * if available. + * + * @param int $plugin_id if of plugin to show manifest */ public function manifest_action($plugin_id) { @@ -491,7 +491,7 @@ class Admin_PluginController extends AuthenticatedController /** * migrate a plugin to top version * - * @param integer id of plugin to migrate + * @param int $plugin_id id of plugin to migrate */ public function migrate_action($plugin_id) { @@ -516,7 +516,7 @@ class Admin_PluginController extends AuthenticatedController * register a plugin in database when it * already exists in file system * - * @param integer number of found plugin + * @param int $number number of found plugin */ public function register_action($number) { diff --git a/app/controllers/admin/sem_classes.php b/app/controllers/admin/sem_classes.php index c0b098f..7993c4b 100644 --- a/app/controllers/admin/sem_classes.php +++ b/app/controllers/admin/sem_classes.php @@ -65,7 +65,7 @@ class Admin_SemClassesController extends AuthenticatedController { Navigation::activateItem("/admin/locations/sem_classes"); - $plugins = PluginManager::getInstance()->getPlugins("StudipModule"); + $plugins = PluginManager::getInstance()->getPlugins(StudipModule::class); $this->sem_class = SemClass::getClasses()[Request::get("id")]; $modules = []; foreach ($this->sem_class->getModuleObjects() as $plugin) { diff --git a/app/controllers/admin/tree.php b/app/controllers/admin/tree.php index 1afc438..c8f2a8f 100644 --- a/app/controllers/admin/tree.php +++ b/app/controllers/admin/tree.php @@ -130,12 +130,15 @@ class Admin_TreeController extends AuthenticatedController $node->parent_id = Request::option('parent_id'); $parent = $classname::getNode(Request::option('parent_id')); - $maxprio = max(array_map( - function ($c) { - return $c->priority; - }, - $parent->getChildNodes() - )); + $children = $parent->getChildNodes(); + $maxprio = !empty($children) + ? max(array_map( + function ($c) { + return $c->priority; + }, + $children + )) + : 0; $node->priority = $maxprio + 1; if (Request::option('studip_object_id')) { diff --git a/app/controllers/admin/user.php b/app/controllers/admin/user.php index 70dfdf1..37a5d2e 100644 --- a/app/controllers/admin/user.php +++ b/app/controllers/admin/user.php @@ -1440,17 +1440,13 @@ class Admin_UserController extends AuthenticatedController ]; $queries[] = [ 'desc' => _("Anzahl der Wikiseiten"), - 'query' => "SELECT COUNT(*) FROM wiki WHERE user_id = ? GROUP BY user_id", + 'query' => "SELECT COUNT(*) FROM `wiki_pages` WHERE `user_id` = ? GROUP BY `user_id`", ]; $queries[] = [ 'desc' => _("Anzahl der Umfragen"), 'query' => "SELECT COUNT(*) FROM questionnaires WHERE user_id = ? GROUP BY user_id", ]; $queries[] = [ - 'desc' => _("Anzahl der Evaluationen"), - 'query' => "SELECT COUNT(*) FROM eval WHERE author_id = ? GROUP BY author_id", - ]; - $queries[] = [ 'desc' => _("Anzahl der Dateien in Veranstaltungen und Einrichtungen"), 'query' => "SELECT COUNT(file_refs.id) FROM (file_refs INNER JOIN files ON file_refs.file_id = files.id) @@ -1478,7 +1474,7 @@ class Admin_UserController extends AuthenticatedController 'details' => "files", ]; - foreach (PluginEngine::getPlugins('ForumModule') as $plugin) { + foreach (PluginEngine::getPlugins(ForumModule::class) as $plugin) { $table = $plugin->getEntryTableInfo(); $queries[] = [ 'desc' => $plugin->getPluginName() . ' - ' . _("Anzahl der Postings"), @@ -1723,7 +1719,7 @@ class Admin_UserController extends AuthenticatedController )->asDialog(); $actions->addLink( _('Konten zusammenführen'), - $this->url_for('admin/user/migrate/' . ((!empty($this->user) && is_array($this->user)) ? $this->user['user_id'] : '')), + $this->url_for('admin/user/migrate/' . (!empty($this->user['user_id']) ? $this->user['user_id'] : '')), Icon::create('community') ); |
