/** * Load the data */ private function loadData() { $modules = BackendModel::getModules(); $userSequence = BackendAuthentication::getUser()->getSetting('dashboard_sequence'); $fs = new Filesystem(); // user sequence does not exist? if (!isset($userSequence)) { // get group ID of user $groupId = BackendAuthentication::getUser()->getGroupId(); // get group preset $userSequence = BackendGroupsModel::getSetting($groupId, 'dashboard_sequence'); } // loop all modules foreach ($modules as $module) { // build pathName $pathName = BACKEND_MODULES_PATH . '/' . $module; // you have sufficient rights? if (BackendAuthentication::isAllowedModule($module) && $fs->exists($pathName . '/Widgets')) { $finder = new Finder(); $finder->name('*.php'); // loop widgets foreach ($finder->files()->in($pathName . '/Widgets') as $file) { /** @ver $file \SplFileInfo */ $widgetName = $file->getBaseName('.php'); $className = 'Backend\\Modules\\' . $module . '\\Widgets\\' . $widgetName; if ($module == 'Core') { $className = 'Backend\\Core\\Widgets\\' . $widgetName; } if (!class_exists($className)) { throw new BackendException('The widgetfile ' . $className . ' could not be found.'); } // present? $present = isset($userSequence[$module][$widgetName]['present']) ? $userSequence[$module][$widgetName]['present'] : false; // if not present, continue if (!$present) { continue; } // create instance /** @var $instance BackendBaseWidget */ $instance = new $className($this->getKernel()); // has rights if (!$instance->isAllowed()) { continue; } // hidden? $hidden = isset($userSequence[$module][$widgetName]['hidden']) ? $userSequence[$module][$widgetName]['hidden'] : false; // execute instance if it is not hidden if (!$hidden) { $instance->execute(); } // user sequence provided? $column = isset($userSequence[$module][$widgetName]['column']) ? $userSequence[$module][$widgetName]['column'] : $instance->getColumn(); $position = isset($userSequence[$module][$widgetName]['position']) ? $userSequence[$module][$widgetName]['position'] : $instance->getPosition(); $title = \SpoonFilter::ucfirst(BL::lbl(\SpoonFilter::toCamelCase($module))) . ': ' . BL::lbl(\SpoonFilter::toCamelCase($widgetName)); $templatePath = $instance->getTemplatePath(); // reset template path if ($templatePath == null) { $templatePath = BACKEND_PATH . '/Modules/' . $module . '/Layout/Widgets/' . $widgetName . '.tpl'; } // build item $item = array('template' => $templatePath, 'module' => $module, 'widget' => $widgetName, 'title' => $title, 'hidden' => $hidden); // add on new position if no position is set or if the position is already used if ($position === null || isset($this->widgets[$column][$position])) { $this->widgets[$column][] = $item; } else { // add on requested position $this->widgets[$column][$position] = $item; } } } } // sort the widgets foreach ($this->widgets as &$column) { ksort($column); } }
/** * Update the widgets * * @param \SpoonFormElement[] $widgetPresets The widgets presets. * @return array */ private function updateWidgets($widgetPresets) { // empty dashboard sequence $this->dashboardSequence = array(); // get users $users = BackendGroupsModel::getUsers($this->id); // loop through users and create objects foreach ($users as $user) { $userObjects[] = new BackendUser($user['id']); } // any users present? if (!empty($userObjects)) { // loop through user objects and get all sequences foreach ($userObjects as $user) { $userSequences[$user->getUserId()] = $user->getSetting('dashboard_sequence'); } } // loop through all widgets foreach ($this->widgetInstances as $widget) { if (!BackendModel::isModuleInstalled($widget['module'])) { continue; } // create instance $instance = new $widget['className']($this->getKernel()); // execute instance $instance->execute(); // create module array if no existence if (!isset($this->dashboardSequence[$widget['module']])) { $this->dashboardSequence[$widget['module']] = array(); } // create dashboard sequence $this->dashboardSequence[$widget['module']] += array($widget['widget'] => array('column' => $instance->getColumn(), 'position' => (int) $instance->getPosition(), 'hidden' => false, 'present' => false)); // loop through selected widgets foreach ($widgetPresets as $preset) { // if selected if ($preset->getChecked()) { // get the preset module name $presetModule = str_replace('widgets_', '', str_replace($widget['widget'], '', $preset->getName())); // if the preset module name matches the widget module name if ($presetModule == $widget['module']) { // remove widgets_[modulename] prefix $selected = str_replace('widgets_' . $widget['module'], '', $preset->getName()); // if right widget set visible if ($selected == $widget['widget']) { $this->dashboardSequence[$widget['module']][$widget['widget']]['present'] = true; } } } } } // build group $userGroup['name'] = $this->frm->getField('name')->getValue(); $userGroup['id'] = $this->id; // build setting $setting['group_id'] = $this->id; $setting['name'] = 'dashboard_sequence'; $setting['value'] = serialize($this->dashboardSequence); // update group BackendGroupsModel::update($userGroup, $setting); // loop through all widgets foreach ($this->widgetInstances as $widget) { // loop through users foreach ($users as $user) { // unset visible if already present if (isset($userSequences[$user['id']][$widget['module']][$widget['widget']])) { $userSequences[$user['id']][$widget['module']][$widget['widget']]['present'] = false; } // get groups for user $groups = BackendGroupsModel::getGroupsByUser($user['id']); // loop through groups foreach ($groups as $group) { // get group sequence $groupSequence = BackendGroupsModel::getSetting($group['id'], 'dashboard_sequence'); // loop through selected widgets foreach ($widgetPresets as $preset) { // if selected if ($preset->getChecked()) { // convert camelcasing to underscore notation $selected = str_replace('widgets_', '', $preset->getName()); // if selected is the right widget if ($selected == $widget['widget']) { // set widgets visible $this->dashboardSequence[$widget['module']][$widget['widget']]['present'] = true; // usersequence has widget? if (isset($userSequences[$user['id']][$widget['module']][$widget['widget']])) { // set visible $userSequences[$user['id']][$widget['module']][$widget['widget']]['present'] = true; } else { // assign module if not yet present if (!isset($userSequences[$user['id']][$widget['module']])) { $userSequences[$user['id']][$widget['module']] = array(); } // add widget $userSequences[$user['id']][$widget['module']] += array($widget['widget'] => array('column' => $instance->getColumn(), 'position' => (int) $instance->getPosition(), 'hidden' => false, 'present' => true)); } } } // widget in visible in other group? if ($groupSequence[$widget['module']][$widget['widget']]['present']) { // set visible $userSequences[$user['id']][$widget['module']][$widget['widget']]['present'] = true; } } } } } // any users present? if (!empty($userObjects)) { // loop through users and update sequence foreach ($userObjects as $user) { $user->setSetting('dashboard_sequence', $userSequences[$user->getUserId()]); } } return $userGroup; }
/** * Validate the form */ private function validateForm() { // is the form submitted? if ($this->frm->isSubmitted()) { // cleanup the submitted fields, ignore fields that were added by hackers $this->frm->cleanupFields(); // email is present if ($this->frm->getField('email')->isFilled(BL::err('EmailIsRequired'))) { // is this an email-address if ($this->frm->getField('email')->isEmail(BL::err('EmailIsInvalid'))) { // was this emailaddress deleted before if (BackendUsersModel::emailDeletedBefore($this->frm->getField('email')->getValue())) { $this->frm->getField('email')->addError(sprintf(BL::err('EmailWasDeletedBefore'), BackendModel::createURLForAction('UndoDelete', null, null, array('email' => $this->frm->getField('email')->getValue())))); } else { // email already exists if (BackendUsersModel::existsEmail($this->frm->getField('email')->getValue())) { $this->frm->getField('email')->addError(BL::err('EmailAlreadyExists')); } } } } // required fields $this->frm->getField('password')->isFilled(BL::err('PasswordIsRequired')); $this->frm->getField('nickname')->isFilled(BL::err('NicknameIsRequired')); $this->frm->getField('name')->isFilled(BL::err('NameIsRequired')); $this->frm->getField('surname')->isFilled(BL::err('SurnameIsRequired')); $this->frm->getField('interface_language')->isFilled(BL::err('FieldIsRequired')); $this->frm->getField('date_format')->isFilled(BL::err('FieldIsRequired')); $this->frm->getField('time_format')->isFilled(BL::err('FieldIsRequired')); $this->frm->getField('number_format')->isFilled(BL::err('FieldIsRequired')); $this->frm->getField('groups')->isFilled(BL::err('FieldIsRequired')); if ($this->frm->getField('password')->isFilled()) { if ($this->frm->getField('password')->getValue() !== $this->frm->getField('confirm_password')->getValue()) { $this->frm->getField('confirm_password')->addError(BL::err('ValuesDontMatch')); } } // validate avatar if ($this->frm->getField('avatar')->isFilled()) { // correct extension if ($this->frm->getField('avatar')->isAllowedExtension(array('jpg', 'jpeg', 'gif', 'png'), BL::err('JPGGIFAndPNGOnly'))) { // correct mimetype? $this->frm->getField('avatar')->isAllowedMimeType(array('image/gif', 'image/jpg', 'image/jpeg', 'image/png'), BL::err('JPGGIFAndPNGOnly')); } } // no errors? if ($this->frm->isCorrect()) { // build settings-array $settings['nickname'] = $this->frm->getField('nickname')->getValue(); $settings['name'] = $this->frm->getField('name')->getValue(); $settings['surname'] = $this->frm->getField('surname')->getValue(); $settings['interface_language'] = $this->frm->getField('interface_language')->getValue(); $settings['date_format'] = $this->frm->getField('date_format')->getValue(); $settings['time_format'] = $this->frm->getField('time_format')->getValue(); $settings['datetime_format'] = $settings['date_format'] . ' ' . $settings['time_format']; $settings['number_format'] = $this->frm->getField('number_format')->getValue(); $settings['csv_split_character'] = $this->frm->getField('csv_split_character')->getValue(); $settings['csv_line_ending'] = $this->frm->getField('csv_line_ending')->getValue(); $settings['password_key'] = uniqid(); $settings['current_password_change'] = time(); $settings['avatar'] = 'no-avatar.gif'; $settings['api_access'] = (bool) $this->frm->getField('api_access')->getChecked(); // get selected groups $groups = $this->frm->getField('groups')->getChecked(); // init var $newSequence = BackendGroupsModel::getSetting($groups[0], 'dashboard_sequence'); // loop through groups and collect all dashboard widget sequences foreach ($groups as $group) { $sequences[] = BackendGroupsModel::getSetting($group, 'dashboard_sequence'); } // loop through sequences foreach ($sequences as $sequence) { // loop through modules inside a sequence foreach ($sequence as $moduleKey => $module) { // loop through widgets inside a module foreach ($module as $widgetKey => $widget) { // if widget present set true if ($widget['present']) { $newSequence[$moduleKey][$widgetKey]['present'] = true; } } } } // add new sequence to settings $settings['dashboard_sequence'] = $newSequence; // build user-array $user['email'] = $this->frm->getField('email')->getValue(); $user['password'] = BackendAuthentication::getEncryptedString($this->frm->getField('password')->getValue(true), $settings['password_key']); // save the password strength $passwordStrength = BackendAuthentication::checkPassword($this->frm->getField('password')->getValue(true)); $settings['password_strength'] = $passwordStrength; // save changes $user['id'] = (int) BackendUsersModel::insert($user, $settings); // has the user submitted an avatar? if ($this->frm->getField('avatar')->isFilled()) { // create new filename $filename = rand(0, 3) . '_' . $user['id'] . '.' . $this->frm->getField('avatar')->getExtension(); // add into settings to update $settings['avatar'] = $filename; // resize (128x128) $this->frm->getField('avatar')->createThumbnail(FRONTEND_FILES_PATH . '/backend_users/avatars/128x128/' . $filename, 128, 128, true, false, 100); // resize (64x64) $this->frm->getField('avatar')->createThumbnail(FRONTEND_FILES_PATH . '/backend_users/avatars/64x64/' . $filename, 64, 64, true, false, 100); // resize (32x32) $this->frm->getField('avatar')->createThumbnail(FRONTEND_FILES_PATH . '/backend_users/avatars/32x32/' . $filename, 32, 32, true, false, 100); } // update settings (in this case the avatar) BackendUsersModel::update($user, $settings); // save groups BackendGroupsModel::insertMultipleGroups($user['id'], $groups); // trigger event BackendModel::triggerEvent($this->getModule(), 'after_add', array('item' => $user)); // everything is saved, so redirect to the overview $this->redirect(BackendModel::createURLForAction('Index') . '&report=added&var=' . $settings['nickname'] . '&highlight=row-' . $user['id']); } } }
/** * Validate the form */ private function validateForm() { // is the form submitted? if ($this->frm->isSubmitted()) { // cleanup the submitted fields, ignore fields that were added by hackers $this->frm->cleanupFields(); $fields = $this->frm->getFields(); // email is present if (!$this->user->isGod()) { if ($fields['email']->isFilled(BL::err('EmailIsRequired'))) { // is this an email-address if ($fields['email']->isEmail(BL::err('EmailIsInvalid'))) { // was this emailaddress deleted before if (BackendUsersModel::emailDeletedBefore($fields['email']->getValue())) { $fields['email']->addError(sprintf(BL::err('EmailWasDeletedBefore'), BackendModel::createURLForAction('UndoDelete', null, null, array('email' => $fields['email']->getValue())))); } elseif (BackendUsersModel::existsEmail($fields['email']->getValue(), $this->id)) { // email already exists $fields['email']->addError(BL::err('EmailAlreadyExists')); } } } } // required fields if ($this->user->isGod() && $fields['email']->getValue() != '' && $this->user->getEmail() != $fields['email']->getValue()) { $fields['email']->addError(BL::err('CantChangeGodsEmail')); } if (!$this->user->isGod()) { $fields['email']->isEmail(BL::err('EmailIsInvalid')); } $fields['nickname']->isFilled(BL::err('NicknameIsRequired')); $fields['name']->isFilled(BL::err('NameIsRequired')); $fields['surname']->isFilled(BL::err('SurnameIsRequired')); $fields['interface_language']->isFilled(BL::err('FieldIsRequired')); $fields['date_format']->isFilled(BL::err('FieldIsRequired')); $fields['time_format']->isFilled(BL::err('FieldIsRequired')); $fields['number_format']->isFilled(BL::err('FieldIsRequired')); if ($this->allowUserRights) { $fields['groups']->isFilled(BL::err('FieldIsRequired')); } if (isset($fields['new_password']) && $fields['new_password']->isFilled()) { if ($fields['new_password']->getValue() !== $fields['confirm_password']->getValue()) { $fields['confirm_password']->addError(BL::err('ValuesDontMatch')); } } // validate avatar if ($fields['avatar']->isFilled()) { // correct extension if ($fields['avatar']->isAllowedExtension(array('jpg', 'jpeg', 'gif', 'png'), BL::err('JPGGIFAndPNGOnly'))) { // correct mimetype? $fields['avatar']->isAllowedMimeType(array('image/gif', 'image/jpg', 'image/jpeg', 'image/png'), BL::err('JPGGIFAndPNGOnly')); } } // no errors? if ($this->frm->isCorrect()) { // build user-array $user['id'] = $this->id; if (!$this->user->isGod()) { $user['email'] = $fields['email']->getValue(true); } if ($this->authenticatedUser->getUserId() != $this->record['id']) { $user['active'] = $fields['active']->isChecked() ? 'Y' : 'N'; } // user is now de-activated, we now remove all sessions for this user so he is logged out immediately if (isset($user['active']) && $user['active'] === 'N' && $this->record['active'] !== $user['active']) { // delete all sessions for user BackendModel::get('database')->delete('users_sessions', 'user_id = ?', array($this->user->getUserId())); } // build settings-array $settings['nickname'] = $fields['nickname']->getValue(); $settings['name'] = $fields['name']->getValue(); $settings['surname'] = $fields['surname']->getValue(); $settings['interface_language'] = $fields['interface_language']->getValue(); $settings['date_format'] = $fields['date_format']->getValue(); $settings['time_format'] = $fields['time_format']->getValue(); $settings['datetime_format'] = $settings['date_format'] . ' ' . $settings['time_format']; $settings['number_format'] = $fields['number_format']->getValue(); $settings['csv_split_character'] = $fields['csv_split_character']->getValue(); $settings['csv_line_ending'] = $fields['csv_line_ending']->getValue(); $settings['api_access'] = $this->allowUserRights ? (bool) $fields['api_access']->getChecked() : $this->record['settings']['api_access']; // update password (only if filled in) if (isset($fields['new_password']) && $fields['new_password']->isFilled()) { $user['password'] = BackendAuthentication::getEncryptedString($fields['new_password']->getValue(), $this->record['settings']['password_key']); // the password has changed if ($this->record['password'] != $user['password']) { // save the login timestamp in the user's settings $lastPasswordChange = BackendUsersModel::getSetting($user['id'], 'current_password_change'); $settings['current_password_change'] = time(); if ($lastPasswordChange) { $settings['last_password_change'] = $lastPasswordChange; } // save the password strength $passwordStrength = BackendAuthentication::checkPassword($fields['new_password']->getValue()); $settings['password_strength'] = $passwordStrength; } } // get user groups when allowed to edit if ($this->allowUserRights) { // get selected groups $groups = $fields['groups']->getChecked(); // init var $newSequence = BackendGroupsModel::getSetting($groups[0], 'dashboard_sequence'); // loop through groups and collect all dashboard widget sequences foreach ($groups as $group) { $sequences[] = BackendGroupsModel::getSetting($group, 'dashboard_sequence'); } // loop through sequences foreach ($sequences as $sequence) { // loop through modules inside a sequence foreach ($sequence as $moduleKey => $module) { // loop through widgets inside a module foreach ($module as $widgetKey => $widget) { // if widget present set true if ($widget['present']) { $newSequence[$moduleKey][$widgetKey]['present'] = true; } } } } // add new sequence to settings $settings['dashboard_sequence'] = $newSequence; } // has the user submitted an avatar? if ($fields['avatar']->isFilled()) { // init vars $avatarsPath = FRONTEND_FILES_PATH . '/backend_users/avatars'; // delete old avatar if it isn't the default-image if ($this->record['settings']['avatar'] != 'no-avatar.jpg' && $this->record['settings']['avatar'] != '') { $fs = new Filesystem(); $fs->remove($avatarsPath . '/source/' . $this->record['settings']['avatar']); $fs->remove($avatarsPath . '/128x128/' . $this->record['settings']['avatar']); $fs->remove($avatarsPath . '/64x64/' . $this->record['settings']['avatar']); $fs->remove($avatarsPath . '/32x32/' . $this->record['settings']['avatar']); } // create new filename $filename = rand(0, 3) . '_' . $user['id'] . '.' . $fields['avatar']->getExtension(); // add into settings to update $settings['avatar'] = $filename; // resize (128x128) $fields['avatar']->createThumbnail($avatarsPath . '/128x128/' . $filename, 128, 128, true, false, 100); // resize (64x64) $fields['avatar']->createThumbnail($avatarsPath . '/64x64/' . $filename, 64, 64, true, false, 100); // resize (32x32) $fields['avatar']->createThumbnail($avatarsPath . '/32x32/' . $filename, 32, 32, true, false, 100); } // save changes BackendUsersModel::update($user, $settings); // save groups if ($this->allowUserRights) { BackendGroupsModel::insertMultipleGroups($this->id, $groups); } // trigger event BackendModel::triggerEvent($this->getModule(), 'after_edit', array('item' => $user)); // can only edit own profile if (!BackendAuthentication::isAllowedAction('Index')) { // everything is saved, so redirect to the edit page $this->redirect(BackendModel::createURLForAction('Edit') . '&id=' . $this->id . '&report=edited&var=' . $settings['nickname']); } else { // everything is saved, so redirect to the overview $this->redirect(BackendModel::createURLForAction('Index') . '&report=edited&var=' . $settings['nickname'] . '&highlight=row-' . $user['id']); } } } }
/** * Get the data to edit */ private function getData() { $this->id = $this->getParameter('id'); // get dashboard sequence $this->hiddenOnDashboard = BackendGroupsModel::getSetting($this->id, 'hidden_on_dashboard'); // get the record $this->record = BackendGroupsModel::get($this->id); // no item found, throw an exceptions, because somebody is f*****g with our URL if (empty($this->record)) { $this->redirect(BackendModel::createURLForAction('Index') . '&error=non-existing'); } $this->getWidgets(); $this->getActions(); $this->bundleActions(); }
/** * Load the data */ private function loadData() { $modules = BackendModel::getModules(); $filesystem = new Filesystem(); // fetch the hidden widgets for all groups the user is in $hiddenWidgets = []; $userGroups = BackendAuthentication::getUser()->getGroups(); $groupCount = count($userGroups); foreach ($userGroups as $group) { foreach (BackendGroupsModel::getSetting($group, 'hidden_on_dashboard') as $module => $widgets) { foreach ($widgets as $widget) { $hiddenWidgets[] = $module . $widget; } } } // only widgets hidden for all user groups should really be hidden $hiddenWidgets = array_count_values($hiddenWidgets); $hiddenWidgets = array_filter($hiddenWidgets, function ($hiddenCount) use($groupCount) { return $hiddenCount === $groupCount; }); // loop all modules foreach ($modules as $module) { // build pathName $pathName = BACKEND_MODULES_PATH . '/' . $module; // you have sufficient rights? if (BackendAuthentication::isAllowedModule($module) && $filesystem->exists($pathName . '/Widgets')) { $finder = new Finder(); $finder->name('*.php'); // loop widgets foreach ($finder->files()->in($pathName . '/Widgets') as $file) { /** @ver $file \SplFileInfo */ $widgetName = $file->getBasename('.php'); $className = 'Backend\\Modules\\' . $module . '\\Widgets\\' . $widgetName; if ($module == 'Core') { $className = 'Backend\\Core\\Widgets\\' . $widgetName; } // if the widget is hidden for all the users groups, don't render it if (array_key_exists($module . $widgetName, $hiddenWidgets)) { continue; } if (!class_exists($className)) { throw new BackendException('The widgetfile ' . $className . ' could not be found.'); } // create instance /** @var $instance BackendBaseWidget */ $instance = new $className($this->getKernel()); // has rights if (!$instance->isAllowed()) { continue; } $instance->execute(); // user sequence provided? $title = \SpoonFilter::ucfirst(BL::lbl(\SpoonFilter::toCamelCase($module))) . ': ' . BL::lbl(\SpoonFilter::toCamelCase($widgetName)); $templatePath = $instance->getTemplatePath(); // reset template path if ($templatePath == null) { $templatePath = '/' . $module . '/Layout/Widgets/' . $widgetName . '.html.twig'; } $templating = $this->get('template'); $content = trim($templating->getContent($templatePath)); if (empty($content)) { continue; } // build item $item = array('content' => $content, 'module' => $module, 'widget' => $widgetName, 'title' => $title); // add on new position if no position is set or if the position is already used $this->widgets[] = $item; } } } }