src/Controller/QAdminController.php line 139

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\Routing\Annotation\Route;
  5. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\RequestStack;
  8. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  9. use Symfony\Contracts\Translation\TranslatorInterface;
  10. use Symfony\Component\Security\Core\Security;
  11. use Symfony\Component\Validator\Validator\ValidatorInterface;
  12. use Knp\Component\Pager\PaginatorInterface;
  13. use App\Form\RoleEditPostmaster;
  14. use App\Form\RoleNew;
  15. use App\Form\QAdmin\AliasEdit;
  16. use App\Form\QAdmin\AliasNew;
  17. use App\Form\QAdmin\DomainNew;
  18. use App\Form\QAdmin\DomainSettings;
  19. use App\Form\QAdmin\Settings;
  20. use App\Form\QAdmin\SystemSettings;
  21. use App\Model\Account;
  22. use App\Model\Domain;
  23. use App\Util\Api;
  24. use App\Util\AppLogger;
  25. use App\Util\AccountTools;
  26. use App\Form\QAdmin\DomainsMass;
  27. use App\Model\LicenseServer;
  28. class QAdminController extends AbstractController
  29. {
  30.     private $logger;
  31.     private $translator;
  32.     private $security;
  33.     private $params;
  34.     private $session;
  35.     private $skin;
  36.     private $requestStack;
  37.     
  38.     public function __construct(AppLogger $loggerTranslatorInterface $translatorSecurity $security,
  39.         ParameterBagInterface $paramsRequestStack $requestStack)
  40.     {
  41.         $this->logger $logger;
  42.         $this->translator $translator;
  43.         $this->security $security;
  44.         $this->params $params;
  45.         $this->requestStack $requestStack;
  46.         $this->session $this->requestStack->getSession();
  47.         
  48.         $defaultSkin 'raw';
  49.         
  50.         if(isset($_SERVER['DEFAULT_SKIN'])) {
  51.             $defaultSkin $_SERVER['DEFAULT_SKIN'];
  52.         }
  53.         
  54.         $account $this->security->getUser()->getAccount();
  55.         
  56.         if(!is_null($account)) { // may be null for superadmin
  57.             $this->skin $account->findSOption('cfgSkin') == null $defaultSkin $account->findSOption('cfgSkin');
  58.         }
  59.         else {
  60.             $this->skin $defaultSkin;
  61.         }
  62.         
  63.         // check if license module should be active
  64.         $licenseModuleEnabled false;
  65.         // if there is a DSN defined
  66.         
  67.         if(in_array('ROLE_SUPER_ADMIN'$this->security->getUser()->getRoleNames()) && isset($_SERVER['LICENSE_SRV_DSN'])) {
  68.             $ls = new LicenseServer();
  69.             $licenseModuleEnabled $ls->shouldBeEnabled();
  70.         }
  71.         
  72.         $this->session->set('license_module_enabled'$licenseModuleEnabled);
  73.         
  74.         QUserController::overwriteEnvs();
  75.     }
  76.     
  77.     /**
  78.      * @Route("/admin", name="qa_main")
  79.      */
  80.     public function index()
  81.     {
  82.         $health = [];
  83.         
  84.         foreach(["api""database""quota"] as $v) {
  85.             $health[$v] = Api::checkSystemHealth($v);
  86.         }
  87.         
  88.         if($health['api']) {
  89.             $version Api::getVersion();
  90.         }
  91.         else {
  92.             $version 'unknown';
  93.         }
  94.         
  95.         $showVersionWarning true;
  96.         
  97.         if(isset($_SERVER['APP_ADMINPANEL_SHOW_VERSION_WARNING']) && $_SERVER['APP_ADMINPANEL_SHOW_VERSION_WARNING'] == 'false') {
  98.             $showVersionWarning false;
  99.         }
  100.     
  101.         return $this->render('skins/' $this->skin '/q_admin/index.html.twig', [
  102.             'systemHealth' => $health,
  103.             'apiVersion' => $version,
  104.             'appVersion' => $this->params->get('app.version.admin'),
  105.             'showVersionWarning' => $showVersionWarning,
  106.         ]);
  107.     }
  108.     
  109.     /**
  110.      * list of roles
  111.      * @Route("/admin/roles", name="qa_roles")
  112.      */
  113.     public function roles(Request $requestPaginatorInterface $paginator)
  114.     {      
  115.         $account $this->security->getUser()->getAccount();
  116.         $this->denyAccessUnlessGranted('ADMIN_ROLES_SHOW'$account);
  117.         
  118.         try{
  119.             $accounts Api::listSpecialAccounts();
  120.         }
  121.         catch(\Exception $e) {
  122.             $this->logger->log('Api::listSpecialAccounts() - exception from API'$request, ['error_code' => $e->getCode(), 'error_message' => $e->getMessage()], 'critical');
  123.             $this->addFlash('error'$this->translator->trans('Critical error, contact administrator.'));
  124.             $accounts = [];
  125.         }
  126.         
  127.         return $this->render('skins/' $this->skin '/q_admin/roles.html.twig', [
  128.             'accounts' => $accounts,
  129.         ]);
  130.     }
  131.     
  132.     /**
  133.      * it's not only for new roles, also for editing existing role
  134.      * @Route("/admin/roles/new/{userName}/{userDomain}/{token}", defaults={"userName"="", "userDomain"="", "token"=""}, name="qa_roles_new_role")
  135.      */
  136.     public function roleNew(string $userName=""string $userDomain=""string $token=""Request $request)
  137.     {
  138.         $account $this->security->getUser()->getAccount();
  139.         $this->denyAccessUnlessGranted('ADMIN_ROLES_NEW'$account);
  140.         
  141.         if($userName != "") {
  142.             $accountEditing Api::getAccount($userName$userDomain);
  143.             
  144.             if($token != $accountEditing->token()) {
  145.                 throw $this->createAccessDeniedException('Invalid token');
  146.             }
  147.         }
  148.         
  149.         $form $this->createForm(RoleNew::class);
  150.         $form->handleRequest($request);
  151.                 
  152.         if($form->isSubmitted() && $form->isValid()) {
  153.             if($form->get('cancel')->isClicked()) {
  154.                 Api::clearRolesTmpData($this->security->getUser()->getEmail() . $userName $userDomain);
  155.                 $this->addFlash('error'$this->translator->trans('Operation cancelled'));
  156.                 return $this->redirectToRoute("qa_roles");
  157.             }
  158.             else {
  159.                 $data $form->getData();
  160.                 $account Api::getAccount($data['accounts'], $data['domains']);
  161.                 
  162. //                 echo "<pre>";
  163. //                 var_dump($data);
  164. //                 exit;
  165.                 
  166.                 if(($data['roles'] == 'ROLE_POSTMASTER') && ($account->getUserName() == 'postmaster')) {
  167.                     // for native postmaster we don't need ROLE_POSTMASTER being set
  168.                     $account->setRole('');
  169.                 }
  170.                 else {
  171.                     $account->setRole($data['roles']);
  172.                 }
  173.                 
  174.                 $allOK false;
  175.                 
  176.                 if(Api::saveAccountParameters($account) ) {
  177.                     if(($data['roles'] == 'ROLE_POSTMASTER_MANY') ||
  178.                         ($data['roles'] == 'ROLE_GROUPMASTER') ||
  179.                         ($data['roles'] == 'ROLE_USERMASTER')
  180.                         ) {
  181.                         if(Api::setRoleDomains($account$data['domainsForRole'])) {
  182.                             if($data['roles'] == 'ROLE_GROUPMASTER' || $data['roles'] == 'ROLE_USERMASTER') {
  183.                                 if(Api::setRoleAccounts($account$data['accountsForRole'])) {
  184.                                     $allOK true;
  185.                                 }
  186.                             }
  187.                             else {
  188.                                 if(Api::deleteRoleAccounts($account)) {
  189.                                     $allOK true;
  190.                                 }
  191.                             }
  192.                         }
  193.                     }
  194.                     else {
  195.                         if(Api::deleteRoleDomains($account)) {
  196.                             if(Api::deleteRoleAccounts($account)) {
  197.                                 $allOK true;
  198.                             }
  199.                         }
  200.                     }
  201.                 }
  202.                     
  203.                 if($allOK) {
  204.                     Api::clearRolesTmpData($this->security->getUser()->getEmail() . $userName $userDomain);
  205.                     $this->addFlash('notice'$this->translator->trans('New role assigned'));
  206.                     return $this->redirectToRoute("qa_roles");
  207.                 }
  208.                 else {
  209.                     $this->addFlash('error'$this->translator->trans('New role NOT assigned'));
  210.                 }
  211.             }   
  212.         }
  213.         elseif($form->isSubmitted() && !$form->isValid()){
  214.             $this->addFlash('error'$this->translator->trans('New role NOT assigned'));
  215.         }
  216.         
  217.         return $this->render('skins/' $this->skin '/q_admin/role_new.html.twig', [
  218.             'form' => $form->createView(),
  219.             'userName' => $userName,
  220.             'userDomain' => $userDomain,
  221.         ]);
  222.     }
  223.     
  224.     /**
  225.      * @Route("/admin/roles/del/{userName}/{userDomain}/{token}", name="qa_roles_del_role")
  226.      */
  227.     public function roleDelete($userName$userDomain$tokenRequest $request)
  228.     {
  229.         $account $this->security->getUser()->getAccount();
  230.         $this->denyAccessUnlessGranted('ADMIN_ROLES_DELETE'$account);
  231.         
  232.         try {
  233.             $account Api::getAccount($userName$userDomain);
  234.             
  235.             if($token != $account->token()) {
  236.                 throw $this->createAccessDeniedException('Invalid token');
  237.             }
  238.             
  239.             $allOK true;
  240.             
  241.             if($account->getRole() == 'ROLE_GROUPMASTER') {
  242.                 if(!Api::setRoleAccounts($account, [])) {
  243.                     $allOK false;
  244.                 }
  245.             }
  246.             
  247.             if(($account->getRole() == 'ROLE_GROUPMASTER') || ($account->getRole() == 'ROLE_POSTMASTER_MANY')) {
  248.                 if(!Api::setRoleDomains($account, [])) {
  249.                     $allOK false;
  250.                 }
  251.             }
  252.             
  253.             $account->setRole('ROLE_USER');
  254.             
  255.             if(!Api::saveAccountParameters($account)) {
  256.                 $allOK false;
  257.             }
  258.             
  259.             if($allOK) {
  260.                 $this->addFlash('notice'$this->translator->trans('Role deleted'));
  261.             }
  262.             else {
  263.                 $this->addFlash('error'$this->translator->trans("Couldn't delete the role"));
  264.             }
  265.         }
  266.         catch(\Exception $e) {
  267.             $this->logger->log('Api::getAccount() or Api::saveAccountParameters() - exception from API'$request, ['error_code' => $e->getCode(), 'error_message' => $e->getMessage()], 'critical');
  268.             $this->addFlash('error'$this->translator->trans('Critical error, contact administrator.'));
  269.             return $this->redirectToRoute("qa_main");
  270.         }
  271.         
  272.         return $this->redirectToRoute("qa_roles");
  273.     }
  274.     /**
  275.      * @Route("/admin/roles/info/{userName}/{userDomain}/{token}", name="qa_roles_info")
  276.      */
  277.     public function roleInfo($userName$userDomain$tokenRequest $request)
  278.     {
  279.         $account $this->security->getUser()->getAccount();
  280.         $this->denyAccessUnlessGranted('ADMIN_ROLES_SHOW'$account);
  281.         
  282.         try {
  283.             $account Api::getAccount($userName$userDomain);
  284.             $domains Api::getRoleDomains($userName$userDomain);
  285.             $accounts AccountTools::orderByDomains(Api::getRoleAccounts($userName$userDomain));
  286.         }
  287.         catch(\Exception $e) {
  288.             $this->logger->log('Api getAccount() or getRoleDomains() - exception from API'$request, ['error_code' => $e->getCode(), 'error_message' => $e->getMessage()], 'critical');
  289.             $this->addFlash('error'$this->translator->trans('Critical error, contact administrator.'));
  290.             return $this->redirectToRoute("qa_main");
  291.         }
  292.             
  293.         if($token != $account->token()) {
  294.             throw $this->createAccessDeniedException('Invalid token');
  295.         }
  296.         
  297.         if($account->getRole() != 'ROLE_GROUPMASTER' && $account->getRole() != 'ROLE_USERMASTER') {
  298.             throw $this->createAccessDeniedException('Invalid role');
  299.         }
  300.            
  301.         return $this->render('skins/' $this->skin '/q_admin/role_info.html.twig', [
  302.             'account' => $account,
  303.             'accounts' => $accounts,
  304.             'domains' => $domains,
  305.         ]);
  306.     }
  307.     /**
  308.      * @Route("/admin/roles/edit-postmaster/{userName}/{userDomain}/{token}", name="deprecated_qa_roles_edit_postmaster")
  309.      */
  310.     /*public function roleEditPostmaster($userName, $userDomain, $token, Request $request)
  311.     {
  312.         $form = $this->createForm(RoleEditPostmaster::class);
  313.         $form->handleRequest($request);
  314.         
  315.         if(!$form->isSubmitted()) {
  316.             $form->get('domains');
  317.             var_dump($x);exit();
  318.         }
  319.         
  320.         if($form->isSubmitted() && $form->isValid()) {
  321.             
  322.         }
  323.         
  324.         try {
  325.             $account = Api::getAccount($userName, $userDomain);
  326.             $domains = Api::getRoleDomains($userName, $userDomain);
  327.         }
  328.         catch(\Exception $e) {
  329.             $this->logger->log('Api::getAccount() or getRoleDomains() - exception from API', $request, ['error_code' => $e->getCode(), 'error_message' => $e->getMessage()], 'critical');
  330.             $this->addFlash('error', $this->translator->trans('Critical error, contact administrator.'));
  331.             return $this->redirectToRoute("qa_main");
  332.         }
  333.         
  334.         if($token != $account->token()) {
  335.             throw $this->createAccessDeniedException('Invalid token');
  336.         }
  337.         
  338.         if($account->getRole() != 'ROLE_POSTMASTER_MANY') {
  339.             throw $this->createAccessDeniedException('Invalid role');
  340.         }
  341.         return $this->render('skins/' . $this->skin . '/q_admin/role_edit_postmaster.html.twig', [
  342.             'account' => $account,
  343.             'domains' => $domains,
  344.             'form' => $form->createView(),
  345.             'perColumn' => 4,
  346.         ]);
  347.     }*/
  348.     
  349.     /**
  350.      * @Route("/admin/domains", name="qa_domains")
  351.      */
  352.     public function domains(Request $request)
  353.     {
  354.         $account $this->security->getUser()->getAccount();
  355.         $this->denyAccessUnlessGranted('ADMIN_DOMAINS_SHOW'$account);
  356.         
  357.         $domains Api::listDomains();
  358.         $form $this->createForm(DomainsMass::class);
  359.         
  360.         $form->handleRequest($request);
  361.         
  362.         if($form->isSubmitted() && $form->isValid()) {
  363.             $selected $request->request->get('domainMassCheckbox');
  364.             $ok true;
  365.             
  366.             foreach($selected as $domain) {
  367.                 if($this->security->getUser()->getUserDomainPart() == $domain) {
  368.                     throw $this->createAccessDeniedException($this->translator->trans("You are not allowed to delete your own domain"));
  369.                 }
  370.                 
  371.                 if(Api::deleteDomain($domain)) {
  372.                     $this->logger->log('domain deleted'$request, ['domain' => $domain]);
  373.                 }
  374.                 else {
  375.                     $this->addFlash('error'$this->translator->trans("Couldn't delete domain") . ' ' $domain);
  376.                     $ok false;
  377.                 }
  378.             }
  379.             
  380.             if($ok) {
  381.                 $this->addFlash('notice'$this->translator->trans('Domain(s) deleted'));
  382.             }
  383.             
  384.             return $this->redirectToRoute('qa_domains');
  385.         }
  386.         
  387.         return $this->render('skins/' $this->skin '/q_admin/domains.html.twig', [
  388.             'domains' => $domains,
  389.             'massForm' => $form->createView(),
  390.         ]);
  391.     }
  392.     
  393.     /**
  394.      * @Route("/admin/domains/new", name="qa_domains_new_domain")
  395.      */
  396.     public function domainNew(Request $requestValidatorInterface $validator)
  397.     {
  398.         $account $this->security->getUser()->getAccount();
  399.         $this->denyAccessUnlessGranted('ADMIN_DOMAINS_NEW'$account);
  400.         
  401.         $form $this->createForm(DomainNew::class);
  402.         $form->handleRequest($request);
  403.         
  404.         $domainErrors = [];
  405.         
  406.         if($form->isSubmitted() && $form->isValid()) {
  407.             foreach(array_unique(explode(','$form->get('domains')->getData())) as $domain) {
  408.                 $testret 0;
  409.                 
  410.                 switch(($testret Api::testAddDomain($domain))) {
  411.                     case 0// domain exists or error in name
  412.                         $this->logger->log('FAILURE while testing - new domain NOT created'$request, ['domain' => $domain]);
  413.                         $this->addFlash('error'$this->translator->trans('New domains NOT added. Problem with a domain: ') . $domain);
  414.                         break;
  415.                         
  416.                     case -1// error
  417.                         $this->logger->log('FAILURE while testing - new domain NOT created'$request, ['domain' => $domain]);
  418.                         $this->addFlash('error'$this->translator->trans('New domains NOT added. Problem with a domain: ') . $domain);
  419.                         
  420.                         break;
  421.                 }
  422.                 
  423.                 if($testret == || $testret == -1) {
  424.                     return $this->render('skins/' $this->skin '/q_admin/domain_new.html.twig', [
  425.                         'form' => $form->createView(),
  426.                         'domainErrors' => $domainErrors,
  427.                     ]);
  428.                 }
  429.             }
  430.             
  431.             $domainsAddedArr = [];
  432.             
  433.             foreach(array_unique(explode(','$form->get('domains')->getData())) as $domain) {
  434.                 try {
  435.                     $domain trim($domain);
  436.                     Api::addDomain($domain);
  437.                
  438.                     // if password provided for postmaster set it now
  439.                     if($form->get('password')->getData() != '') {
  440.                         if(!Api::changePassword('postmaster'$domain$form->get('password')->getData())) {
  441.                             $this->logger->log('FAILURE while changing password for postmaster'$request, ['domain' => $domain]);
  442.                             $this->addFlash('warning'$this->translator->trans('New domain(s) added, but password for postmaster not set. Domain: ' $domain));
  443.                         }
  444.                         else {
  445.                             $this->logger->log('domain added'$request, ['domain' => $domain]);
  446.                         }
  447.                     }
  448.                     else {
  449.                         $this->logger->log('domain added'$request, ['domain' => $domain]);
  450.                     }
  451.                     
  452.                     $domainsAddedArr[] = $domain;
  453.                 }
  454.                 catch(\Exception $e) {
  455.                     $this->logger->log('FAILURE while adding - new domain NOT created'$request, ['domain' => $domain'code' => $e->getCode()]);
  456.                     $this->addFlash('error'$this->translator->trans('New domains NOT added. Problem with a domain: ') . $domain);
  457.                     return $this->render('skins/' $this->skin '/q_admin/domain_new.html.twig', [
  458.                         'form' => $form->createView(),
  459.                         'domainErrors' => $domainErrors,
  460.                     ]);
  461.                 }                                
  462.             }
  463.             
  464.             $this->addFlash('notice'$this->translator->trans('New domain(s) added') . ': ' implode(', '$domainsAddedArr));
  465.             
  466.             return $this->redirectToRoute('qa_domains_new_domain');
  467.         }
  468.         elseif($form->isSubmitted() && !$form->isValid()){
  469.             $errors $form['domains']->getErrors();
  470.             
  471.             // there are errors in usernames field. Check which one is problematic
  472.             if(count($errors)) {
  473.                 foreach(explode(','$form->get('domains')->getData()) as $d) {
  474.                     if(!preg_match(Domain::DOMAIN_REGEX$d)) {
  475.                         $domainErrors[] = $this->translator->trans('Domain contains illegal characters');
  476.                     }
  477.                     else {
  478.                         if(!preg_match('/\./'$d)) {
  479.                             $domainErrors[] = $this->translator->trans('Domain name must contain a dot');
  480.                         }
  481.                         else {
  482.                             $testret Api::testAddDomain($d);
  483.                             
  484.                             if($testret == 0) {
  485.                                 $domainErrors[] = $this->translator->trans('Domain already exists');
  486.                             }
  487.                             elseif($testret == -1) {
  488.                                 $domainErrors[] = $this->translator->trans('Unknown error while adding a domain');
  489.                             }
  490.                             else {
  491.                                 $domainErrors[] = '';
  492.                             }
  493.                         }
  494.                     }
  495.                 }
  496.             }
  497.             
  498.             $this->addFlash('error'$this->translator->trans('New domain(s) NOT added'));
  499.         }
  500.         
  501.         return $this->render('skins/' $this->skin '/q_admin/domain_new.html.twig', [
  502.             'form' => $form->createView(),
  503.             'domainErrors' => $domainErrors,
  504.         ]);
  505.     }
  506.     
  507.     /**
  508.      * @Route("/admin/domains/del/{domain}", name="qa_domains_del_domain")
  509.      */
  510.     public function domainDelete($domainRequest $request)
  511.     {        
  512.         $account $this->security->getUser()->getAccount();
  513.         $this->denyAccessUnlessGranted('ADMIN_DOMAINS_SHOW'$account);
  514.         
  515.         // don't allow delete your own domain
  516.         if($this->security->getUser()->getUserDomainPart() == $domain) {
  517.             throw $this->createAccessDeniedException($this->translator->trans("You are not allowed to delete your own domain"));
  518.         }
  519.         
  520.         if(Api::deleteDomain($domain)) {
  521.             $this->logger->log('domain deleted'$request, ['domain' => $domain]);
  522.             $this->addFlash('notice'$this->translator->trans('Domain deleted'));
  523.         }
  524.         else {
  525.             $this->addFlash('error'$this->translator->trans("Couldn't delete domain"));
  526.         }
  527.         
  528.         return $this->redirectToRoute("qa_domains");
  529.     }
  530.     
  531.     /**
  532.      * @Route("/admin/domains/edit/{domain}", name="qa_domains_edit_domain")
  533.      */
  534.     public function domainEdit($domainRequest $request)
  535.     {        
  536.         $account $this->security->getUser()->getAccount();        
  537.         $this->denyAccessUnlessGranted('ADMIN_DOMAINS_SHOW'$account);
  538.         
  539.         $form $this->createForm(DomainSettings::class);
  540.         $form->handleRequest($request);
  541.         
  542.         if(!$form->isSubmitted()) {            
  543.             // restrictQuotaUsage
  544.             $form->get('restrictQuotaUsage')->setData('no');
  545.             
  546.             try {
  547.                 $d Api::getDomain($domain);
  548.                 
  549.                 if($d->findOption('restrictQuotaUsage')) {
  550.                     $form->get('restrictQuotaUsage')->setData('yes');
  551.                 }
  552.             }
  553.             catch(\Exception $e) {
  554.             }
  555.         }
  556.         
  557.         if($form->isSubmitted() && $form->isValid()) {
  558.             // check if destination account exists
  559.             $success false;
  560.             
  561.             $d Api::getDomain($domain);
  562.             
  563.             if($form->get('restrictQuotaUsage')->getData() == 'yes') {
  564.                 $d->setOption('restrictQuotaUsage''yes');
  565.             }
  566.             else {
  567.                 $d->deleteOption('restrictQuotaUsage');
  568.             }
  569.             
  570.             if(Api::saveDomain($d)) {
  571.                 $success true;
  572.                 $this->logger->log('Settings (parameters) for domain ' $domain ' saved'$request, ['accountName' => $account->getUsername()]);
  573.             }
  574.             else {
  575.                 $success false;
  576.                 $this->logger->log('Error while saving parameters for domain ' $domain$request, ['accountName' => $account->getUsername()]);
  577.             }
  578.             
  579.             if($success) {
  580.                 $this->addFlash('notice'$this->translator->trans('Settings saved'));
  581.             }
  582.             else {
  583.                 $this->addFlash('error'$this->translator->trans('Settings NOT saved'));
  584.             }
  585.             
  586.             return $this->redirectToRoute('qa_domains_edit_domain', ['domain' => $domain]);
  587.         }
  588.         elseif($form->isSubmitted() && !$form->isValid()){
  589.             $this->addFlash('error'$this->translator->trans('Settings NOT saved'));
  590.         }
  591.         
  592.         return $this->render('skins/' $this->skin '/q_admin/domain_settings.html.twig', [
  593.             'form' => $form->createView(),
  594.             'domain' => $domain,
  595.         ]);
  596.     }
  597.     
  598.     /**
  599.      * @Route("/admin/aliases", name="qa_aliases")
  600.      */
  601.     public function aliases(Request $request)
  602.     {
  603.         $account $this->security->getUser()->getAccount();
  604.         $this->denyAccessUnlessGranted('ADMIN_ALIASES_SHOW'$account);
  605.         
  606.         $aliases Api::listDomainsAliases();
  607.         $form $this->createForm(DomainsMass::class);
  608.         
  609.         $form->handleRequest($request);
  610.         
  611.         if($form->isSubmitted() && $form->isValid()) {
  612.             $selected $request->request->get('aliasMassCheckbox');
  613.             $ok true;
  614.             
  615.             foreach($selected as $alias) {
  616.                 if($this->security->getUser()->getUserDomainPart() == $alias) {
  617.                     throw $this->createAccessDeniedException($this->translator->trans("You are not allowed to delete your own domain"));
  618.                 }
  619.                 
  620.                 if(Api::deleteDomainAlias($alias)) {
  621.                     $this->logger->log('alias deleted'$request, ['alias' => $alias]);
  622.                 }
  623.                 else {
  624.                     $this->addFlash('error'$this->translator->trans("Couldn't delete alias") . ' ' $alias);
  625.                     $ok false;
  626.                 }
  627.             }
  628.             
  629.             if($ok) {
  630.                 $this->addFlash('notice'$this->translator->trans('Alias(es) deleted'));
  631.             }
  632.             
  633.             return $this->redirectToRoute('qa_aliases');
  634.         }
  635.         
  636.         return $this->render('skins/' $this->skin '/q_admin/aliases.html.twig', [
  637.             'aliases' => $aliases,
  638.             'massForm' => $form->createView(),
  639.         ]);
  640.     }
  641.     
  642.     
  643.     /**
  644.      * @Route("/admin/aliases/new", name="qa_aliases_new_alias")
  645.      */
  646.     public function aliasNew(Request $requestValidatorInterface $validator)
  647.     {
  648.         $account $this->security->getUser()->getAccount();
  649.         $this->denyAccessUnlessGranted('ADMIN_ALIASES_NEW'$account);
  650.         
  651.         $form $this->createForm(AliasNew::class);
  652.         $form->handleRequest($request);
  653.         
  654.         $aliasErrors = [];
  655.         
  656.         if($form->isSubmitted() && $form->isValid()) {
  657.             // check if this alias or domain doesn't exist            
  658.             foreach(explode(','$form->get('aliases')->getData()) as $alias) {
  659.                 $testret 0;
  660.                 
  661.                 switch(($testret Api::testAddDomain($alias))) {
  662.                     case 0// domain exists or error in name
  663.                         $this->logger->log('FAILURE while testing - new domain alias NOT created, domain already exists'$request, ['alias' => $alias]);
  664.                         $this->addFlash('error'$this->translator->trans('New aliases NOT added, domain already exists. Problem with a name: ') . $alias);
  665.                         break;
  666.                         
  667.                     case -1// error
  668.                         $this->logger->log('FAILURE while testing - new domain alias NOT created'$request, ['alias' => $alias]);
  669.                         $this->addFlash('error'$this->translator->trans('New alias NOT added. Problem with a name: ') . $alias);
  670.                         
  671.                         break;
  672.                 }
  673.                 
  674.                 if($testret == || $testret == -1) {
  675.                     return $this->render('skins/' $this->skin '/q_admin/alias_new.html.twig', [
  676.                         'form' => $form->createView(),
  677.                         'aliasErrors' => $aliasErrors,
  678.                     ]);
  679.                 }
  680.             }
  681.             
  682.             $aliasesAddedArr = [];
  683.             $domain $form->get('domain')->getData();
  684.             
  685.             foreach(explode(','$form->get('aliases')->getData()) as $alias) {
  686.                 try {
  687.                     $alias trim($alias);
  688.                     Api::addDomainAlias($alias$domain);
  689.                     
  690.                     $this->logger->log('domain alias added'$request, ['alias' => $alias'domain' => $domain]);
  691.                     
  692.                     $aliasesAddedArr[] = $alias;
  693.                 }
  694.                 catch(\Exception $e) {
  695.                     $this->logger->log('FAILURE while adding - new domain alias NOT created'$request, ['alias' => $alias'domain' => $domain'code' => $e->getCode()]);
  696.                     $this->addFlash('error'$this->translator->trans('New aliases NOT added. Problem with a name: ') . $alias);
  697.                     return $this->render('skins/' $this->skin '/q_admin/alias_new.html.twig', [
  698.                         'form' => $form->createView(),
  699.                         'aliasErrors' => $aliasErrors,
  700.                     ]);
  701.                 }
  702.             }
  703.             
  704.             $this->addFlash('notice'$this->translator->trans('New alias(es) added') . ': ' implode(', '$aliasesAddedArr));
  705.             
  706.             return $this->redirectToRoute('qa_aliases_new_alias');
  707.         }
  708.         elseif($form->isSubmitted() && !$form->isValid()){            
  709.             $errors $form['aliases']->getErrors();
  710.             //var_dump(count($errors));
  711.             
  712.             /*foreach($errors as $e) {
  713.                 echo "e msg = " . $e->getMessage();
  714.             }
  715.             
  716.             echo "form not valid" ; exit;*/
  717.             // there are errors in aliases field. Check which one is problematic
  718.             if(count($errors)) {
  719.                 
  720.                 foreach(explode(','$form->get('aliases')->getData()) as $a) {
  721.                     if(!preg_match(Domain::DOMAIN_REGEX$a)) {
  722.                         $aliasErrors[] = $this->translator->trans('Alias contains illegal characters');
  723.                     }
  724.                     else {
  725.                         if(!preg_match('/\./'$a)) {
  726.                             $aliasErrors[] = $this->translator->trans('Alias name must contain a dot');
  727.                         }
  728.                         else {
  729.                             $testret Api::testAddDomain($a);
  730.                             
  731.                             if($testret == 0) {
  732.                                 $aliasErrors[] = $this->translator->trans('Domain / alias already exists');
  733.                             }
  734.                             elseif($testret == -1) {
  735.                                 $aliasErrors[] = $this->translator->trans('Unknown error while adding an alias');
  736.                             }
  737.                             else {
  738.                                 $aliasErrors[] = '';
  739.                             }
  740.                         }
  741.                     }
  742.                 }
  743.             }
  744.             
  745.             $this->addFlash('error'$this->translator->trans('New alias(es) NOT added'));
  746.         }
  747.         
  748.         return $this->render('skins/' $this->skin '/q_admin/alias_new.html.twig', [
  749.             'form' => $form->createView(),
  750.             'aliasErrors' => $aliasErrors,
  751.         ]);
  752.     }
  753.     
  754.     /**
  755.      * @Route("/admin/aliases/del/{alias}", name="qa_aliases_del_alias")
  756.      */
  757.     public function aliasDelete($aliasRequest $request)
  758.     {
  759.         $account $this->security->getUser()->getAccount();
  760.         $this->denyAccessUnlessGranted('ADMIN_ALIASES_SHOW'$account);
  761.         
  762.         if(Api::deleteDomainAlias($alias)) {
  763.             $this->logger->log('alias deleted'$request, ['alias' => $alias]);
  764.             $this->addFlash('notice'$this->translator->trans('Alias deleted'));
  765.         }
  766.         else {
  767.             $this->addFlash('error'$this->translator->trans("Couldn't delete alias"));
  768.         }
  769.         
  770.         return $this->redirectToRoute("qa_aliases");
  771.     }
  772.     
  773.     /**
  774.      * @Route("/admin/aliases/edit/{alias}/{domain}", name="qa_aliases_edit_alias")
  775.      */
  776.     public function aliasEdit($alias$domainRequest $request)
  777.     {
  778.         $account $this->security->getUser()->getAccount();
  779.         $this->denyAccessUnlessGranted('ADMIN_ALIASES_SHOW'$account);
  780.         
  781.         $form $this->createForm(AliasEdit::class);
  782.         $form->handleRequest($request);
  783.         
  784.         if(!$form->isSubmitted()) {
  785.             // restrictQuotaUsage
  786.             $form->get('alias')->setData($alias);
  787.             
  788.         }
  789.         
  790.         if($form->isSubmitted() && $form->isValid()) {
  791.             $newAlias $form->get('alias')->getData();
  792.             $success false;
  793.             
  794.             if($alias == $newAlias) {
  795.                 $this->addFlash('notice'$this->translator->trans('No change detected'));
  796.             }
  797.             else {
  798.                 // check if it's possible to create a new one
  799.                 switch(Api::testAddDomain($newAlias)) {
  800.                     case 0// domain exists or error in name
  801.                     case -1// error
  802.                         $this->addFlash('error'$this->translator->trans('Alias NOT edited, problem with a name'));
  803.                         
  804.                         return $this->render('skins/' $this->skin '/q_admin/alias_edit.html.twig', [
  805.                         'form' => $form->createView(),
  806.                         'alias' => $alias,
  807.                         'domain' => $domain,
  808.                         ]);
  809.                         break;
  810.                 }
  811.                 
  812.                 // remove old alias, create a new one
  813.                 if(Api::deleteDomainAlias($alias) == false) {
  814.                     $this->logger->log('Deleting alias ' $alias ' for a domain FAILED'$request, ['alias' => $alias]);
  815.                     $this->addFlash('error'$this->translator->trans('Alias editing error (delete not possible)'));
  816.                 }
  817.                 else {
  818.                     try {
  819.                         if(Api::addDomainAlias($newAlias$domain) == false) {
  820.                             $this->logger->log('Adding alias ' $alias ' for a domain ' $domain ' FAILED'$request, ['domain' => $domain'alias' => $alias]);
  821.                             $this->addFlash('error'$this->translator->trans('Alias editing error (adding not possible)'));
  822.                         }
  823.                         else {
  824.                             $success true;
  825.                         }
  826.                     }
  827.                     catch(\Exception $e) {
  828.                         $this->logger->log('Adding alias ' $alias ' for a domain ' $domain ' FAILED'$request, ['domain' => $domain'alias' => $alias]);
  829.                         $this->addFlash('error'$this->translator->trans('Alias editing error (adding not possible)'));
  830.                     }
  831.                 }
  832.                 
  833.             }
  834.             
  835.             if($success) {
  836.                 $this->addFlash('notice'$this->translator->trans('Changes saved'));
  837.                 return $this->redirectToRoute('qa_aliases_edit_alias', ['domain' => $domain'alias' => $newAlias]);
  838.             }
  839.             else {
  840.                 $this->addFlash('error'$this->translator->trans('Changes NOT saved'));
  841.                 
  842.                 return $this->render('skins/' $this->skin '/q_admin/alias_edit.html.twig', [
  843.                     'form' => $form->createView(),
  844.                     'alias' => $alias,
  845.                     'domain' => $domain,
  846.                 ]);
  847.             }
  848.             
  849.             
  850.         }
  851.         elseif($form->isSubmitted() && !$form->isValid()){
  852.             $this->addFlash('error'$this->translator->trans('Changes NOT saved'));
  853.         }
  854.         
  855.         return $this->render('skins/' $this->skin '/q_admin/alias_edit.html.twig', [
  856.             'form' => $form->createView(),
  857.             'alias' => $alias,
  858.             'domain' => $domain,
  859.         ]);
  860.     }
  861.     
  862.     /**
  863.      * @Route("/admin/logs", name="qa_logs")
  864.      */
  865.     public function logs(Request $request)
  866.     {
  867.         $account $this->security->getUser()->getAccount();
  868.         $this->denyAccessUnlessGranted('ADMIN_LOGS'$account);
  869.         
  870.         $lines = [];
  871.         /*$lines[] = ["date" => '2019-08-07 11:56:08', "type" => 'app.INFO', 'message' => 'SUCCESS - user logged in',
  872.             'details' => '{"moduleName":"app_login","loggedinUser":"c3@namysql.pl","sessionId":"2dko0njtvdkask236koaq3rdfh"}'
  873.         ];*/
  874.         /*$lines[] = ["date" => '2019-08-07 11:56:08', "level" => 'app.INFO', 'message' => 'SUCCESS - user logged in',
  875.             'details' => ["moduleName" => "app_login", "loggedinUser" => "c3@namysql.pl",
  876.             "sessionId" => "2dko0njtvdkask236koaq3rdfh"]
  877.         ];*/
  878.         
  879.         return $this->render('skins/' $this->skin '/q_admin/logs.html.twig', [
  880.             'lines' => $lines,
  881.         ]);
  882.     }
  883.     
  884.     /**
  885.      * @Route("/admin/system/settings", name="qa_system_settings")
  886.      */
  887.     public function systemSettings(Request $request)
  888.     {
  889.         $account $this->security->getUser()->getAccount();
  890.         $this->denyAccessUnlessGranted('ADMIN_SYSTEM_SETTINGS'$account);
  891.         
  892.         $account $this->security->getUser()->getAccount();
  893.         $form $this->createForm(SystemSettings::class);
  894.         $form->handleRequest($request);
  895.         
  896.         if(!$form->isSubmitted()) {
  897. /*            $form->get('restrictQuotaUsage')->setData('no');
  898.             
  899.             try {
  900.                 $d = Api::getDomain($domain);
  901.                 
  902.                 if($d->findOption('restrictQuotaUsage')) {
  903.                     $form->get('restrictQuotaUsage')->setData('yes');
  904.                 }
  905.             }
  906.             catch(\Exception $e) {
  907.             }*/
  908.         }
  909.         
  910.         if($form->isSubmitted() && $form->isValid()) {
  911.             // check if destination account exists
  912.             /*$success = false;
  913.             
  914.             $d = Api::getDomain($domain);
  915.             
  916.             if($form->get('restrictQuotaUsage')->getData() == 'yes') {
  917.                 $d->setOption('restrictQuotaUsage', 'yes');
  918.             }
  919.             else {
  920.                 $d->deleteOption('restrictQuotaUsage');
  921.             }
  922.             
  923.             if(Api::saveDomain($d)) {
  924.                 $success = true;
  925.                 $this->logger->log('Settings (parameters) for domain ' . $domain . ' saved', $request, ['accountName' => $account->getUsername()]);
  926.             }
  927.             else {
  928.                 $success = false;
  929.                 $this->logger->log('Error while saving parameters for domain ' . $domain, $request, ['accountName' => $account->getUsername()]);
  930.             }
  931.             
  932.             if($success) {
  933.                 $this->addFlash('notice', $this->translator->trans('Settings saved'));
  934.             }
  935.             else {
  936.                 $this->addFlash('error', $this->translator->trans('Settings NOT saved'));
  937.             }*/
  938.             
  939.             return $this->redirectToRoute('qa_system_settings');
  940.         }
  941.         elseif($form->isSubmitted() && !$form->isValid()){
  942.             $this->addFlash('error'$this->translator->trans('Settings NOT saved'));
  943.         }
  944.         
  945.         return $this->render('skins/' $this->skin '/q_admin/system_settings.html.twig', [
  946.             'form' => $form->createView(),
  947.         ]);
  948.     }
  949.     
  950.     /**
  951.      * @Route("/admin/system/status", name="qa_system_status")
  952.      */
  953.     public function systemStatus(Request $request)
  954.     {
  955.         $account $this->security->getUser()->getAccount();
  956.         $this->denyAccessUnlessGranted('ADMIN_SYSTEM_STATUS'$account);
  957.         
  958.         $account $this->security->getUser()->getAccount();
  959.         
  960.         try {
  961.             $status Api::getSystemStatus();
  962.         }
  963.         catch(\Exception $e) {
  964.             $this->addFlash('error'$this->translator->trans('Error while getting system status'));
  965.             return $this->redirectToRoute('qa_main');
  966.         }
  967.         
  968.         return $this->render('skins/' $this->skin '/q_admin/system_status.html.twig', [
  969.             's' => $status,
  970.         ]);
  971.     }
  972.     
  973.     /**
  974.      * @Route("/admin/master", name="qa_master")
  975.      */
  976.     public function master(Request $request)
  977.     {        
  978.         return $this->render('skins/' $this->skin '/q_admin/master.html.twig');
  979.     }
  980.     
  981.     /**
  982.      * @Route("/admin/panel-info", name="qa_panel_info")
  983.      */
  984.     public function panelInfo()
  985.     {
  986.         $license Api::getLicense();
  987.         $sys = [];
  988.         $sys['version'] = $this->params->get('app.version.postmaster');
  989.         $sys['apiVersion'] = Api::getVersion();
  990.         $sys['apiVersionString'] = Api::getVersionString();
  991.         $sys['licensed'] = $license['company'];
  992.         $sys['expires'] = $license['expires'];
  993.         $sys['plan'] = $license['plan'];
  994.         $sys['domains'] = $license['domains'];
  995.         
  996.         return $this->render('skins/' $this->skin '/q_admin/panel_info.html.twig', [
  997.             'sys' => $sys,
  998.         ]);
  999.     }
  1000.     
  1001.     /**
  1002.      * @Route("/admin/charts", name="qa_charts")
  1003.      */
  1004.     public function charts(Request $request)
  1005.     {
  1006.         $account $this->security->getUser()->getAccount();
  1007.         $this->denyAccessUnlessGranted('ADMIN_CHARTS'$account);
  1008.         
  1009.         if(isset($_SERVER['APP_CHARTS'])) {
  1010.             $configArr AccountTools::envToArray($_SERVER['APP_CHARTS']);
  1011.             
  1012.             if(is_array($configArr)) {
  1013.                 $chartsConfig $this->_parseChartsConfig($configArr);
  1014.             }
  1015.             else {
  1016.                 $chartsConfig = [];
  1017.             }
  1018.         }
  1019.         else {
  1020.             $chartsConfig = [];
  1021.         }
  1022.         
  1023.         return $this->render('skins/' $this->skin '/q_admin/charts.html.twig', [
  1024.             'config' => $chartsConfig,
  1025.         ]);
  1026.     }
  1027.     
  1028.     /**
  1029.      * generates javascript for charts, depending on .env configuration
  1030.      * @Route("/app_init_qadmin_charts.js", name="js_init_charts")
  1031.      */
  1032.     public function jsAppInitCharts(Request $request)
  1033.     {
  1034.         $account $this->security->getUser()->getAccount();
  1035.         $this->denyAccessUnlessGranted('ADMIN_CHARTS'$account);
  1036.         
  1037.         $js '';
  1038.         
  1039.         if(isset($_SERVER['APP_CHARTS'])) {
  1040.             $chartsConfig $this->_parseChartsConfig(AccountTools::envToArray($_SERVER['APP_CHARTS']));
  1041.         }
  1042.         else {
  1043.             $chartsConfig = [];
  1044.         }
  1045.         
  1046.         $i 1;
  1047.         
  1048.         foreach($chartsConfig as $conf) {
  1049.             $js .= 'let ' $conf['type'] . $i ' = new ' $this->_chartTypeToClass($conf);
  1050.             $js .= "(c3, initApiEndpoint, '#chart-wrapper" $i "'";
  1051.             
  1052.             // parameters if needed for a type 
  1053.             if($conf['type'] == 'qdisk') {
  1054.                 if(count($conf['params']) > 0) {
  1055.                     $js .= ", '" $conf['params'][0] . "'";
  1056.                 }
  1057.                 else {
  1058.                     $js .= ", ''";
  1059.                 }
  1060.             }
  1061.             elseif($conf['type'] == 'qconnections') {
  1062.                 if(count($conf['params']) > 0) {
  1063.                     $js .= ", [";
  1064.                     
  1065.                     foreach($conf['params'] as $param) {
  1066.                         if($param != 'double') {
  1067.                             $js .= "'" $param "',";
  1068.                         }
  1069.                     }
  1070.                     
  1071.                     $js rtrim($js','); 
  1072.                     $js .= "]";
  1073.                 }
  1074.                 else {
  1075.                     $js .= ", []";
  1076.                 }
  1077.             }
  1078.             elseif($conf['type'] == 'qmemlines') {
  1079.                 if(count($conf['params']) > 0) {
  1080.                     $js .= ", " $conf['params'][0];
  1081.                 }
  1082.             }
  1083.             
  1084.             $js .= ");\n";
  1085.             
  1086.             // additional settings
  1087.             if($conf['type'] == 'qmemlines' || $conf['type'] == 'qmembars') {
  1088.                 $js .=  $conf['type'] . $i ".setTotalMem(initTotalMem);\n";
  1089.                 $js .= $conf['type'] . $i ".setFixedRange(chartsFixedRange);\n"
  1090.             }
  1091.             elseif($conf['type'] == 'qload') {
  1092.                 $js .= $conf['type'] . $i ".setMaxYAxis(initUserOptions['cfgChartLoadAvgRange']);\n";
  1093.                 $js .= $conf['type'] . $i ".setFixedRange(chartsFixedRange);\n";
  1094.             }
  1095.             
  1096.             $js .= $conf['type'] . $i ".generateChart();\n";
  1097.             $js .= $conf['type'] . $i ".genNewChartData();\n";
  1098.             
  1099.             $i++;
  1100.         }
  1101.                 
  1102.         return $this->render('app_init_qadmin_charts.js.twig', [
  1103.             'js' => $js,
  1104.         ]);
  1105.     }
  1106.     
  1107.     /**
  1108.      * @Route("/admin/settings", name="qa_settings")
  1109.      */
  1110.     public function settings(Request $request)
  1111.     {
  1112.         $account $this->security->getUser()->getAccount();
  1113.         
  1114.         $form $this->createForm(Settings::class);
  1115.         $form->handleRequest($request);
  1116.         
  1117.         if(!$form->isSubmitted()) {
  1118.             $chartsFixedRange $account->findSOption('cfgChartsFixedRange') == null 'no' $account->findSOption('cfgChartsFixedRange');
  1119.             $chartLoadAvgRange $account->findSOption('cfgChartLoadAvgRange') == null Account::LOAD_AVG_DEFAULT_RANGE  $account->findSOption('cfgChartLoadAvgRange');
  1120.             
  1121.             $form->get('chartsFixedRange')->setData($chartsFixedRange);
  1122.             $form->get('chartLoadAvgRange')->setData($chartLoadAvgRange);
  1123.         }
  1124.         
  1125.         if($form->isSubmitted() && $form->isValid()) {            
  1126.             $account->setSOption('cfgChartsFixedRange'str_replace(',''.'$form->get('chartsFixedRange')->getData()));
  1127.             
  1128.             if($form->get('chartLoadAvgRange')->getData()) {
  1129.                 $account->setSOption('cfgChartLoadAvgRange'$form->get('chartLoadAvgRange')->getData());
  1130.             }
  1131.             
  1132.             if(Api::saveAccountParameters($account)) {
  1133.                 $this->addFlash('notice'$this->translator->trans('Settings saved'));
  1134.                 $this->logger->log('Settings for account saved'$request, ['accountName' => $account->getUsername()]);
  1135.             }
  1136.             else {
  1137.                 $this->addFlash('error'$this->translator->trans('Settings NOT saved'));
  1138.                 $this->logger->log('Error while saving settings for account'$request, ['accountName' => $account->getUsername()]);
  1139.             }
  1140.             
  1141.             return $this->redirectToRoute('qa_settings');
  1142.         }
  1143.         elseif($form->isSubmitted() && !$form->isValid()){
  1144.             $this->addFlash('error'$this->translator->trans('Settings NOT saved'));
  1145.         }
  1146.         
  1147.         return $this->render('skins/' $this->skin '/q_admin/settings.html.twig', [
  1148.             'form' => $form->createView(),
  1149.         ]);
  1150.     }
  1151.     
  1152.     // parses qchart config returning array of associative arrays
  1153.     // keys: type: String, params: array
  1154.     private function _parseChartsConfig(Array $config) : Array
  1155.     {
  1156.         $retArr = [];
  1157.         
  1158.         if(!is_array($config)) {
  1159.             return $retArr;
  1160.         }
  1161.         
  1162.         foreach($config as $conf) {
  1163.             $elem = [];
  1164.             $confArr explode('='$conf);
  1165.             $elem['type'] = $confArr[0];
  1166.             
  1167.             if(sizeof($confArr) > 1) {
  1168.                 $paramsArr explode(':'$confArr[1]);
  1169.                 
  1170.                 $elem['params'] = $paramsArr;
  1171.             }
  1172.             else {
  1173.                 $elem['params'] = [];
  1174.             }
  1175.             
  1176.             $elem['name'] = $this->_chartTypeToName($elem);
  1177.             $retArr[] = $elem;
  1178.         }
  1179.         
  1180.         return $retArr;
  1181.     }
  1182.     
  1183.     private function _chartTypeToName($elem) : String
  1184.     {
  1185.         switch($elem['type']) {
  1186.             case 'qload':
  1187.                 return 'Load avg';
  1188.                 
  1189.             case 'qdisk':
  1190.                 return 'Disk usage';
  1191.                 
  1192.             case 'qqueue':
  1193.                 return 'Mail queue';
  1194.                 
  1195.             case 'qconnections':
  1196.                 return 'SMTP / IMAP4 / POP3 activity';
  1197.         
  1198.             case 'qmemlines':
  1199.                 if((count($elem['params']) > 0) && ($elem['params'][0] == '0')) {
  1200.                     return 'Free mem';
  1201.                 }
  1202.                 else {
  1203.                     return 'Used mem';
  1204.                 }
  1205.                 
  1206.             case 'qmembars':
  1207.                 return 'Free & Used mem';
  1208.         }
  1209.         
  1210.         return 'Unknown'
  1211.     }
  1212.     
  1213.     private function _chartTypeToClass($elem) : String
  1214.     {
  1215.         switch($elem['type']) {
  1216.             case 'qload':
  1217.                 return 'QLoadAvg';
  1218.                 
  1219.             case 'qdisk':
  1220.                 return 'QDisk';
  1221.                 
  1222.             case 'qqueue':
  1223.                 return 'QQueue';
  1224.                 
  1225.             case 'qconnections':
  1226.                 return 'QConnections';
  1227.                 
  1228.             case 'qmemlines':
  1229.                 return 'QMemLines';
  1230.                 
  1231.             case 'qmembars':
  1232.                 return 'QMemBars';
  1233.                 
  1234.         }
  1235.         
  1236.         return 'Unknown';
  1237.     }
  1238. }