app = $app; if ($intern) { return; } $this->service = $this->app->Container->get('WizardService'); $this->app->ActionHandlerInit($this); $this->app->ActionHandler('list', 'WizardList'); $this->app->ActionHandler('ajax', 'WizardAjax'); $this->app->ActionHandler('create', 'WizardCreate'); $this->app->ActionHandlerListen($app); } /** * @return void */ public function Install() { $this->app->erp->CheckTable('wizard'); $this->app->erp->CheckColumn('id', 'int(11)', 'wizard', 'NOT NULL AUTO_INCREMENT'); $this->app->erp->CheckColumn('user_id', 'INT(11)', 'wizard', "DEFAULT '0' NOT NULL"); $this->app->erp->CheckColumn('key', 'VARCHAR(32)', 'wizard', "DEFAULT '' NOT NULL"); $this->app->erp->CheckColumn('title', 'VARCHAR(64)', 'wizard', "DEFAULT '' NOT NULL"); $this->app->erp->CheckColumn('skip_link_text', 'VARCHAR(64)', 'wizard', 'DEFAULT NULL'); $this->app->erp->CheckColumn('params', 'VARCHAR(512)', 'wizard', 'DEFAULT NULL'); $this->app->erp->CheckColumn('options', 'VARCHAR(512)', 'wizard', 'NULL DEFAULT NULL'); $this->app->erp->CheckColumn('active', 'TINYINT(1)', 'wizard', "DEFAULT '1' NOT NULL"); $this->app->erp->CheckColumn('created_at', 'DATETIME', 'wizard', 'DEFAULT CURRENT_TIMESTAMP NOT NULL'); $this->app->erp->CheckIndex('wizard', ['user_id', 'key'], true); $this->app->erp->CheckTable('wizard_step'); $this->app->erp->CheckColumn('id', 'int(11)', 'wizard_step', 'NOT NULL AUTO_INCREMENT'); $this->app->erp->CheckColumn('wizard_id', 'INT(11)', 'wizard_step', "DEFAULT '0' NOT NULL"); $this->app->erp->CheckColumn('key', 'VARCHAR(32)', 'wizard_step', "DEFAULT '' NOT NULL"); $this->app->erp->CheckColumn('link', 'VARCHAR(255)', 'wizard_step', "DEFAULT '' NOT NULL"); $this->app->erp->CheckColumn('title', 'VARCHAR(64)', 'wizard_step', "DEFAULT '' NOT NULL"); $this->app->erp->CheckColumn('caption', 'VARCHAR(255)', 'wizard_step', 'DEFAULT NULL'); $this->app->erp->CheckColumn('description', 'TEXT', 'wizard_step', "DEFAULT '' NOT NULL"); $this->app->erp->CheckColumn('options', 'VARCHAR(512)', 'wizard_step', 'DEFAULT NULL'); $this->app->erp->CheckColumn('position', 'TINYINT(3)', 'wizard_step', "DEFAULT '0' NOT NULL"); $this->app->erp->CheckColumn('checked', 'TINYINT(1)', 'wizard_step', "DEFAULT '0' NOT NULL"); $this->app->erp->CheckColumn('created_at', 'DATETIME', 'wizard_step', 'DEFAULT CURRENT_TIMESTAMP NOT NULL'); $this->app->erp->CheckIndex('wizard_step', ['wizard_id', 'key'], true); $this->app->erp->CheckAlterTable('ALTER TABLE `wizard_step` CHANGE `description` `description` TEXT NOT NULL; '); $this->app->erp->RegisterHook('before_final_parse_page', 'wizard', 'checkForActiveWizard'); } public function checkForActiveWizard() { $this->service = $this->app->Container->get('WizardService'); $userId = $this->app->User->GetID(); if($userId === null) { return; } if ($activeWizardKey = $this->service->getActiveWizardKey($userId)) { $this->app->Tpl->Set('ACTIVE_WIZARD_KEY', $activeWizardKey); $this->app->Tpl->Parse('BODYENDE', 'active_wizard.tpl'); } } /** * @return void */ protected function WizardMenu() { $this->app->erp->MenuEintrag('index.php?module=wizard&action=create', 'Neuen Wizard anlegen'); $this->app->erp->MenuEintrag('index.php?module=wizard&action=list', 'Übersicht'); $this->app->Tpl->Set('UEBERSCHRIFT', 'Wizard'); $this->app->erp->Headlines('Wizard'); $this->app->Tpl->Set('TABTEXT', 'Wizard'); } /** * @return void */ public function WizardList() { $this->WizardMenu(); $cmd = $this->app->Secure->GetGET('cmd'); if ($cmd === 'loadexample') { $data = $this->GetExampleWizardData(); $data['settings']['active'] = true; try { $this->service->replaceWizard($data, $this->app->User->GetID()); } catch (Exception $e) { } } $this->app->Tpl->Parse('PAGE', 'wizard_list.tpl'); } /** * @return void */ public function WizardCreate() { $this->WizardMenu(); $jsonOutput = ''; $selectedUserId = 0; $cmd = $this->app->Secure->GetGET('cmd'); switch ($cmd) { // JSON einlesen case 'jsoninput': $createWizardJsonRaw = $this->app->Secure->GetPOST('createwizard_json'); $selectedUserId = $this->app->Secure->GetPOST('createwizard_user'); if (!empty($createWizardJsonRaw)) { $createWizardJson = str_replace('\r\n', '', $createWizardJsonRaw); $createWizardJson = stripslashes($createWizardJson); $data = json_decode($createWizardJson, true); if (json_last_error() > 0) { $message = sprintf('JSON konnte nicht gelesen werden. Code "%s" - Meldung "%s"', json_last_error(), json_last_error_msg()); $this->app->Tpl->Set('MESSAGE', '
' . htmlspecialchars($message, ENT_QUOTES) . '
'); $jsonOutput = stripslashes(str_replace('\r\n', "\r\n", $createWizardJsonRaw)); break; } try { // JSON konnte fehlerfrei dekodiert werden $overwriteUserId = (int)$selectedUserId > 0 ? $selectedUserId : null; $wizardId = $this->service->replaceWizard($data, $overwriteUserId); $this->app->Tpl->Set('MESSAGE', '
Wizard wurde erfolgreich gespeichert.
'); // JSON aus den gespeicherten Daten neu generieren $data = $this->service->generateTemplateFromExistingWizard($wizardId); $jsonOutput = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } catch (WizardExceptionInterface $e) { $message = htmlspecialchars($e->getMessage(), ENT_QUOTES); $this->app->Tpl->Set('MESSAGE', '
Konnte Wizard nicht erstellen. Fehler: ' . $message . '
'); $jsonOutput = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } } break; // JSON von einem vorhandenen Wizard laden case 'loadwizard': if (!empty($this->app->Secure->GetPOST('loadwizard_button'))) { $loadWizardId = (int)$this->app->Secure->GetPOST('loadwizard_selected'); $data = $this->service->generateTemplateFromExistingWizard($loadWizardId); $selectedUserId = $data['settings']['user_id']; $jsonOutput = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } break; case 'loadexample': $data = $this->GetExampleWizardData(); $jsonOutput = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); break; case 'deletewizard': $deleteWizardId = (int)$this->app->Secure->GetPOST('deletewizard_selected'); $this->service->deleteWizardById($deleteWizardId); break; } $this->app->Tpl->Set('CREATEWIZARDJSON', $jsonOutput); $this->app->Tpl->Set('CREATEWIZARDUSEROPTIONS', $this->GenerateUserSelectOptions($selectedUserId)); $this->app->Tpl->Set('LOADWIZARDOPTIONS', $this->GenerateWizardSelectOptions()); $this->app->Tpl->Parse('PAGE', 'wizard_create.tpl'); } /** * @return JsonResponse|\Xentral\Components\Http\RedirectResponse */ public function WizardAjax() { $userId = $this->app->User->GetID(); $cmd = $this->app->Secure->GetGET('cmd'); switch ($cmd) { case 'save_visit': $wizardKey = $this->app->Secure->GetPOST('wizard'); $stepKey = $this->app->Secure->GetPOST('step'); $success = $this->service->setStepVisited($wizardKey, $stepKey, $userId); $data = ['success' => $success]; break; case 'deactivate_wizard': try { $wizardKey = $this->app->Secure->GetPOST('wizard'); $this->service->deactivateWizard($wizardKey, $userId); $data = ['success' => true]; } catch (WizardExceptionInterface $e) { $data = ['success' => false, 'error' => $e->getMessage()]; } break; case 'cancel_active_wizard': try { $this->service->cancelActiveWizardForUser($userId); $data = ['success' => true]; } catch (WizardExceptionInterface $e) { $data = ['success' => false, 'error' => $e->getMessage()]; } break; case 'finish_wizard': try { $wizardKey = $this->app->Secure->GetGET('key'); $this->service->finishWizardForUser($wizardKey, $userId); $data = ['success' => true]; } catch (WizardExceptionInterface $e) { $data = ['success' => false, 'error' => $e->getMessage()]; } break; case 'reset_wizard': try { $wizardKey = $this->app->Secure->GetGET('key'); $this->service->resetWizardForUser($wizardKey, $userId); $data = ['success' => true]; } catch (WizardExceptionInterface $e) { $data = ['success' => false, 'error' => $e->getMessage()]; } break; case 'get_wizards': $data = []; $wizardKeys = $this->service->getActiveWizardKeys($userId); foreach ($wizardKeys as $wizardKey) { $wizardData = $this->service->getWizard($wizardKey, $userId); $data[] = $wizardData; } break; case 'get_by_key': $key = $this->app->Secure->GetGET('key'); $userId = $this->app->User->getId(); $data = $this->service->getWizard($key, $userId); break; case 'set_active_wizard': $key = $this->app->Secure->GetGET('key'); $userId = $this->app->User->getId(); if($this->service->isWizardCompletedForUser($key, $userId)){ $this->service->resetWizardForUser($key,$userId); } $this->service->setActiveWizardKey($key, $userId); $this->service->setMinimizedForUser($userId, false); $link = $this->service->getFirstWizardLink($key); return \Xentral\Components\Http\RedirectResponse::createFromUrl($link); break; case 'complete_step': $key = $this->app->Secure->GetGET('key'); $completedStep = $this->app->Secure->GetPOST('step'); $lastVisitedLink = $this->app->Secure->GetPOST('link'); $userId = $this->app->User->getId(); $this->service->setStepVisited($key, $completedStep, $userId); $this->service->saveLastVisitedLink($key, $lastVisitedLink, $userId); $data = ['success' => true]; break; case 'set_minimized': $state = $this->app->Secure->GetGET('value'); $isMinimized = $state === 'true'; $userId = $this->app->User->getId(); $isMinimized = $this->service->setMinimizedForUser($userId, $isMinimized); $data = ['success' => true, 'is_minimized' => $isMinimized]; break; default: $data = ['success' => false, 'error' => 'Incomplete request']; break; } return new JsonResponse( $data, $data['success'] === false ? JsonResponse::HTTP_NOT_FOUND : JsonResponse::HTTP_OK ); } /** * Test-Callback-Methode für die 'check_callback'-Option * * @return bool */ public function CheckArticlesProvidedCallback() { $articleCount = $this->app->DB->Select( 'SELECT COUNT(a.id) FROM `artikel` AS `a` WHERE a.geloescht = 0' ); return (int)$articleCount > 10; } /** * @return array */ protected function GetExampleWizardData() { $settings = [ 'user_id' => $this->app->User->GetID(), 'active' => true, 'key' => 'firstrun', 'title' => 'Einrichtungsassistent', 'skip_link_text' => 'Einrichtung überspringen', 'params' => [ 'shop_id' => 1, ] ]; $steps = [ [ 'key' => 'grundeinstellungen', 'link' => './index.php?module=firmendaten&action=edit#tabs-1', 'title' => 'Grundeinstellungen', 'caption' => 'Meine Firmen-Informationen pflegen ', 'description' => 'Bitte tragen Sie hier Ihren Firmennamen und bla bla ein. ', 'position' => 1, ], [ 'key' => 'briefkopf', 'link' => './index.php?module=firmendaten&action=edit#tabs-2', 'title' => 'Briefkopf einrichten', 'caption' => 'Aussehen der Geschäftsbriefe anpassen', 'position' => 2, 'options' => [ 'highlight' => [ 'breite_position', 'breite_nummer' ] ], ], [ 'key' => 'artikel', 'link' => './index.php?module=artikel&action=list', 'title' => 'Artikel pflegen', 'caption' => 'Beispiel mit Modul-Callback', 'position' => 3, 'description' => 'Beispiel mit Modul-Callback. Anforderungen:
Callback-Methode muss public sein und Rückgabe ' . 'muss zu bool wandelbar sein.', 'options' => [ 'check_callback' => [ 'module_name' => 'Wizard', 'module_action' => 'CheckArticlesProvidedCallback', 'args' => [ 'Wert für erstes Callback-Argument', 'Zweites Argument mit ##shop_id## Parameter' ], ], ] ], [ 'key' => 'adressen', 'link' => './index.php?module=adresse&action=list', 'title' => 'Adressen pflegen', 'caption' => 'Beispiel mit Objekt-Protokoll-Prüfung', 'position' => 4, 'options' => [ 'check_protocol' => [ 'object_name' => 'shop', 'action_name' => 'shop_created', 'object_id' => '##shop_id##', ], ] ], ]; return [ 'settings' => $settings, 'steps' => $steps ]; } /** * @param int $selectedUserId * * @return string */ protected function GenerateUserSelectOptions($selectedUserId) { $data = $this->app->DB->SelectArr( 'SELECT u.id, a.name FROM `user` AS `u` INNER JOIN `adresse` AS `a` ON u.adresse = a.id ORDER BY a.name ASC' ); $html = ''; $selectedUserId = (int)$selectedUserId; foreach ($data as $row) { $selectedAttr = $selectedUserId === (int)$row['id'] ? ' selected="selected"' : ''; $html .= sprintf( '', $row['id'], $selectedAttr, $row['name'] ); } return $html; } /** * @return string */ protected function GenerateWizardSelectOptions() { $data = $this->app->DB->SelectArr( 'SELECT w.id, w.key, w.title, w.active, w.user_id, a.name AS username FROM `wizard` AS `w` LEFT JOIN `user` AS `u` ON w.user_id = u.id INNER JOIN `adresse` AS `a` ON u.adresse = a.id WHERE 1 ORDER BY w.user_id ASC, w.created_at ASC' ); $html = ''; foreach ($data as $row) { $html .= sprintf( '', $row['id'], $row['username'], $row['user_id'], $row['title'], (int)$row['active'] === 1 ? 'aktiv' : 'inaktiv' ); } return $html; } }