diff --git a/README.md b/README.md
index 4d0e627..c2f832c 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,87 @@
-giftlist
-========
+# Presentlist / Geschenkeliste #
-Eine Geschenkliste / a Presentlist / ein Wunschzettel
+=> !! For English => english is under german !!
+
+Presentlist ist eine Geschenkliste auf der man seine Wünsche zur Hochzeit, Geburtstag oder anderen Anlässen auflisten kann. Dabei kann man einen Titel, Beschreibung und auch ein Bild zum Geschnenk angeben, sowie Links zu Händlern oder dem Produkt angeben. Wenn sich dann jemand ein Geschenk von der Liste nimmt, ist es für die anderen nicht mehr sichtbar. Man kann gewählte Geschenke aber auch wieder freigeben und der Administrator sieht nicht wer sich welches Geschenk genommen hat.
+
+![](https://raw2.github.com/lightszentip/giftlist/gh-pages/screenshot01.PNG)
+![](https://raw2.github.com/lightszentip/giftlist/gh-pages/screenshot03.PNG)
+![](https://raw2.github.com/lightszentip/giftlist/gh-pages/screenshot04.PNG)
+
+## Funktionen ##
+- Install Wizard
+- Geschenkeliste
+- Detail Ansicht von Geschenken
+- Geschenk auswählen
+- Geschenk freigeben
+- Geschenk per Mail teilen
+- Backend
+ - Geschenk anlegen / editieren / löschen
+ - Benutzer anlegen
+ - Profil editieren
+ - Passwort vergessen
+ - Login / Logout
+ - Wartungsmodus aktivieren
+ - Einstellungen ändern
+
+
+## Requirements ##
+
+- PHP 5.3.7 oder höher
+- MySQL Datenbank (andere sind aktuell nur durch bearbeiten der Sources möglich)
+- PHP PDO Support für MySQL aktiv (extension=php_pdo_mysql.dll)
+
+
+## Anleitung ##
+
+Die Zip Datei im gewüschten Ordner entpacken und die Url zum Ordner aufrufen. Danach wird man auf den Install Wizard weitergeleitet. Nach dem ausführen des Install Wizard den setup Ordner löschen. Danach sich anmelden und das Passwort und die Email Adresse des Admin Benutzers ändern. Durch das Ändern des Benutzernamens wird zudem die Sicherheit erhöht.
+
+Bei Fragen/Problemen/Erweiterungen und Feedback stehe ich gerne zur Verfügung. Entweder per Email oder durch erstellen eines Issues.
+
+## English ##
+
+The app presentlist is show the wishes from wedding, birthday or from other occasions. You can create a present with a title, description, image and links. If a user take a present from the list, it is not visible for other user.
+
+
+
+## Functions ##
+- Install Wizard
+- list with presents
+- detail view of present
+- use a present
+- release a gift
+- Backend
+ - create, edit, delete a present
+ - create user
+ - edit profile
+ - forgotten password
+ - Login / Logout
+ - maintenance mode
+ - change settings
+
+
+## Requirements ##
+
+- PHP 5.3.7 or higher
+- MySQL Database (other database only support by you edit the source files)
+- PHP PDO Support for MySQL active (extension=php_pdo_mysql.dll)
+
+
+## Instructions ##
+
+Unpack the zip file to the target dir and open the url in your browser. Follow the steps of install wizard. Delete the setup folder and change the password and email address of admin account.
+
+If you have a question, problems or feedback then you can send a mail or create a new issue.
+
+## Verwendete PHP Libraries / Used lbraries: ##
+
+- Rain TPL => [https://github.com/rainphp/raintpl](https://github.com/rainphp/raintpl)
+- php-i18n von Philipp Schröer=> [https://github.com/Philipp15b/php-i18n?files=1](https://github.com/Philipp15b/php-i18n?files=1)
+- Medoo DB => [http://medoo.in/api/new](http://medoo.in/api/new)
+- PHP Setup / Installer Script => [http://www.effiziente-webprogrammierung.info/php-scripts/setup-wizard-installer](http://www.effiziente-webprogrammierung.info/php-scripts/setup-wizard-installer)
+- PHP Login von http://www.php-login.net/ => [https://github.com/panique/php-login](https://github.com/panique/php-login) -> Version Advanced
+
+## Verwendete JS/HTML/CSS Komponeneten / Used JS/HTML/CSS components: ##
+
+- TableSorter von Christian Bach => [http://mottie.github.io/tablesorter/](https://github.com/Mottie/tablesorter)
+- Bootstrap 3.1 => [http://getbootstrap.com/](http://getbootstrap.com/)
\ No newline at end of file
diff --git a/app/classes/controller/ControllerAdminStartpage.php b/app/classes/controller/ControllerAdminStartpage.php
new file mode 100644
index 0000000..f106d79
--- /dev/null
+++ b/app/classes/controller/ControllerAdminStartpage.php
@@ -0,0 +1,73 @@
+ view = new BackendView($login->getSecurityModel());
+ $this -> request = $request;
+ $this -> messageResolver = AppFactory::getMessageResolver();
+ $this -> presentDao = new PresentDao($jdbcTemplate);
+ }
+
+ /**
+ * Process data
+ */
+ public function process() {
+ $presentlist = $this -> presentDao -> getAll();
+ $this -> view -> assign("presents", $presentlist -> getItems());
+ $success = null;
+ if(!empty($this -> request['get']['success'])) {
+ $success = EscapeHelper::escape($this -> request['get']['success'], EscapeHelper::TARGET_STRING);
+ }
+ $isErrorPresent = false;
+ $isChangePresent = false;
+ if (!empty($success) && ($success == "createPresent" || $success == "editPresent" || $success == "deletePresent")) {
+ $args = EscapeHelper::escape($this -> request['get']['args'], EscapeHelper::TARGET_STRING);
+ $parameter = base64_decode($args);
+ list($paramPresentId, $paramResult) = split("&", $parameter);
+ $presentId = EscapeHelper::escape(str_replace("presentId=", "", $paramPresentId), EscapeHelper::TARGET_NUMBER);
+ if ($success == "createPresent") {
+ $present = $this -> presentDao -> getById($presentId);
+ $isChangePresent = true;
+ $this -> view -> assign("infomessage", $this -> messageResolver -> getMessage("adminpresenttable_create_present", $present -> getTitle()));
+ } else if ($success == "editPresent") {
+ $present = $this -> presentDao -> getById($presentId);
+ $isChangePresent = true;
+ $this -> view -> assign("infomessage", $this -> messageResolver -> getMessage("adminpresenttable_edit_present", $present -> getTitle()));
+ } else if ($success == "deletePresent") {
+ $result = EscapeHelper::escape(str_replace("result=", "", $paramResult), EscapeHelper::TARGET_STRING);
+ if ($result == 1) {
+ $isChangePresent = true;
+ $this -> view -> assign("infomessage", $this -> messageResolver -> getMessage("adminpresenttable_delete_present", $presentId));
+ } else {
+ $isErrorPresent = true;
+ $this -> view -> assign("errormessage", $this -> messageResolver -> getMessage("adminpresenttable_delete_present_error", $presentId));
+ }
+ }
+ }
+ $this -> view -> assign("changePresent", $isChangePresent);
+ $this -> view -> assign("errorPresent", $isErrorPresent);
+ }
+ /**
+ * Display Content
+ * @return type
+ */
+ public function display() {
+ $this -> view -> setTemplate("backend_presenttable");
+ $this -> view -> assign("view", "list");
+ $this -> view -> assign("messageResolver", $this -> messageResolver);
+ return $this -> view -> loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerCreateEditPresent.php b/app/classes/controller/ControllerCreateEditPresent.php
new file mode 100644
index 0000000..3f3e73b
--- /dev/null
+++ b/app/classes/controller/ControllerCreateEditPresent.php
@@ -0,0 +1,144 @@
+view = new BackendView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->presentDao = new PresentDao($jdbcTemplate);
+ }
+
+ /**
+ *
+ */
+ public function process() {
+ $isNew = null;
+ if (!empty($this->request['post']['checknew'])) {
+ $isNew = EscapeHelper::escape($this->request['post']['checknew'], EscapeHelper::TARGET_STRING);
+ }
+ $error = new ErrorModel();
+ $isError = false;
+ $isEdit = false;
+ if ($isNew == "true") {
+ $title = EscapeHelper::escape($this->request['post']['title'], EscapeHelper::TARGET_STRING);
+ $description = EscapeHelper::escape($this->request['post']['description'], EscapeHelper::TARGET_STRING);
+ $imagePath = EscapeHelper::escape($this->request['post']['imagePath'], EscapeHelper::TARGET_STRING);
+ $links = EscapeHelper::escape($this->request['post']['links'], EscapeHelper::TARGET_STRING);
+ if (HelperUtil::isNullOrEmptyString($title)) {
+ $error->addErrorField("title", "error_present_create_empty_title");
+ } else {
+ if (strlen($title) > 50) {
+ $error->addErrorField("title", "error_present_create_size_title");
+ }
+ }
+ if (!empty($imagePath)) {
+ if (!$this->str_starts_with($imagePath, "http")) {
+ $imagePath = "http://" . $imagePath;
+ }
+ if (!filter_var($imagePath, FILTER_VALIDATE_URL)) {
+ $error->addErrorField("title", "error_present_create_invalid_imagepath");
+ }
+ }
+ if (!empty($description) && strlen($description) > 1200) {
+ $error->addErrorField("description", "error_present_create_size_description");
+ }
+ if (!empty($links)) {
+
+ function notEmpty($var) {
+ // Gibt zurück, ob der Eingabewert gerade ist
+ return (!(!isset($var) || trim($var) === '' || empty($var)));
+ }
+
+ $links = array_filter($links, "notEmpty");
+ }
+ if (count($links) == 0) {
+ $links = null;
+ }
+ $present = new PresentModel();
+ $present->setTitle($title);
+ $present->setDescription($description);
+ $present->setImagePath($imagePath);
+ $present->setLinks($links);
+ if ($error->hasError()) {
+ $editId = EscapeHelper::escape($this->request['post']['editId'], EscapeHelper::TARGET_NUMBER);
+ if (!empty($editId)) {
+ $present->setId($editId);
+ }
+ $this->view->assign("present", $present);
+ } else {
+ $editId = EscapeHelper::escape($this->request['post']['editId'], EscapeHelper::TARGET_NUMBER);
+ if (!empty($editId)) {
+ $present->setId($editId);
+ $id = $this->presentDao->update($present);
+ if ($id != null) {
+ $targetLocation = APP_URL . "?mapping=admin&success=editPresent&args=" . base64_encode("presentId=$id");
+ header("Location: $targetLocation");
+ } else {
+ $error->addErrorField("present", $this->messageResolver->getMessage("error_present_create_db"));
+ $this->view->assign("present", $present);
+ }
+ } else {
+ $id = $this->presentDao->createPresent($present);
+ if ($id != null) {
+ $targetLocation = APP_URL . "?mapping=admin&success=createPresent&args=" . base64_encode("presentId=$id");
+ header("Location: $targetLocation");
+ } else {
+ $error->addErrorField("present", $this->messageResolver->getMessage("error_present_create_db"));
+ $this->view->assign("present", $present);
+ }
+ }
+ }
+ } else {
+ //edit ?
+ $presendId = EscapeHelper::escape($this->request['get']['id'], EscapeHelper::TARGET_NUMBER);
+ if (!empty($presendId)) {
+ $present = $this->presentDao->getById($presendId);
+ if ($present != null && $present->getStatus() != 1) {
+ $this->view->assign("present", $present);
+ $isEdit = true;
+ } else {
+ $this->view->assign("present", new PresentModel());
+ $isError = true;
+ }
+ } else {
+ $this->view->assign("present", new PresentModel());
+ }
+ }
+ $this->view->assign("isError", $isError);
+ $this->view->assign("isEdit", $isEdit);
+ $this->view->assign("error", $error);
+ }
+
+ /**
+ *
+ * @return type
+ */
+ public function display() {
+ $this->view->setTemplate("backend_createeditpresent");
+ $this->view->assign("messageResolver", $this->messageResolver);
+ return $this->view->loadTemplate();
+ }
+
+ private function str_starts_with($haystack, $needle) {
+ return substr_compare($haystack, $needle, 0, strlen($needle)) === 0;
+ }
+
+ private function str_ends_with($haystack, $needle) {
+ return substr_compare($haystack, $needle, -strlen($needle)) === 0;
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/app/classes/controller/ControllerCreateUser.php b/app/classes/controller/ControllerCreateUser.php
new file mode 100644
index 0000000..e197f91
--- /dev/null
+++ b/app/classes/controller/ControllerCreateUser.php
@@ -0,0 +1,35 @@
+view = new BackendView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->login = $login;
+ }
+
+ public function process() {
+ $this->login->processRegister();
+ }
+
+ public function display() {
+ $this->view->setTemplate($this->login->getRegisterView());
+ $this->view->assign("messageResolver", $this->messageResolver);
+ $this->view->assign($this->login->getRegisterViewVars());
+ $this->view->assign("isRegisterConfirm", false);
+ return $this->view->loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerDeletePresent.php b/app/classes/controller/ControllerDeletePresent.php
new file mode 100644
index 0000000..ff37da6
--- /dev/null
+++ b/app/classes/controller/ControllerDeletePresent.php
@@ -0,0 +1,41 @@
+view = new BackendView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->presentDao = new PresentDao($jdbcTemplate);
+ }
+
+ public function process() {
+ $present = null;
+ if (!empty($this->request['get']['presentId'])) {
+ $presentId = EscapeHelper::escape($this->request['get']['presentId'], EscapeHelper::TARGET_NUMBER);
+ $present = $this->presentDao->getById($presentId);
+ }
+ $targetLocation = null;
+ if ($present != null && $present->getStatus() != 1) {
+ $result = $this->presentDao->delete($presentId);
+ if ($result) {
+ $targetLocation = APP_URL . "?mapping=admin&success=deletePresent&args=" . base64_encode("presentId=$presentId&result=1");
+ } else {
+ $targetLocation = APP_URL . "?mapping=admin&success=deletePresent&args=" . base64_encode("presentId=$presentId&result=2");
+ }
+ } else {
+ $targetLocation = APP_URL . "?mapping=admin&success=deletePresent&args=" . base64_encode("presentId=$presentId&result=2");
+ }
+ header("Location: $targetLocation");
+ }
+
+ public function display() {
+ return $this->view->loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerLogin.php b/app/classes/controller/ControllerLogin.php
new file mode 100644
index 0000000..12e19ef
--- /dev/null
+++ b/app/classes/controller/ControllerLogin.php
@@ -0,0 +1,50 @@
+view = new LoginView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ if (empty($this->request['post']['next'])) {
+ $this->target = $defaultTarget;
+ } else {
+ $this->target = EscapeHelper::escape($this->request['post']['next'], EscapeHelper::TARGET_STRING);
+ }
+ $this->isError = false;
+ $this->login = $login;
+ }
+
+ public function process() {
+ if (!$this->login->isAppLoggedIn()) {
+ $targetLocation = APP_URL . "?mapping=" . $this->target;
+ $this->isError = $this->login->appLoginRequest($targetLocation);
+ } else {
+ $targetLocation = APP_URL . "?mapping=" . $this->target;
+ header("Location: $targetLocation");
+ }
+ }
+
+ public function display() {
+ $this->view->setTemplate($this->login->getLoginView());
+ $this->view->assign("messageResolver", $this->messageResolver);
+ $this->view->assign($this->login->getLoginViewVars());
+ $this->view->assign("target", $this->target);
+ $this->view->assign("isErrorMessage", $this->isError);
+ return $this->view->loadTemplate();
+ }
+
+}
diff --git a/app/classes/controller/ControllerLogout.php b/app/classes/controller/ControllerLogout.php
new file mode 100644
index 0000000..8da495c
--- /dev/null
+++ b/app/classes/controller/ControllerLogout.php
@@ -0,0 +1,24 @@
+login = $login;
+ }
+
+ public function process() {
+ $this->login->appLogout();
+ $targetLocation = APP_URL;
+ header("Location: $targetLocation");
+ }
+
+ public function display() {
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerMaintenance.php b/app/classes/controller/ControllerMaintenance.php
new file mode 100644
index 0000000..9f35a9a
--- /dev/null
+++ b/app/classes/controller/ControllerMaintenance.php
@@ -0,0 +1,32 @@
+ view = new FrontendView();
+ $this -> messageResolver = AppFactory::getMessageResolver();
+ $this -> configDao = new ConfigDao($jdbcTemplate);
+ }
+
+ public function process() {
+ $this -> view -> assign("title", $this -> configDao->getByKey($this->confModeKeyTitle));
+ $this -> view -> assign("subtitle", $this -> configDao->getByKey($this->confModeKeySubtitle));
+ }
+
+ public function display() {
+ $this -> view -> setTemplate("maintenance");
+ return $this -> view -> loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerMaintenanceSettings.php b/app/classes/controller/ControllerMaintenanceSettings.php
new file mode 100644
index 0000000..c64cf95
--- /dev/null
+++ b/app/classes/controller/ControllerMaintenanceSettings.php
@@ -0,0 +1,85 @@
+view = new BackendView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->configDao = new ConfigDao($jdbcTemplate);
+ }
+
+ public function process() {
+ $isNew = null;
+ $success = null;
+ if (!empty($this->request['post']['checknew'])) {
+ $isNew = EscapeHelper::escape($this->request['post']['checknew'], EscapeHelper::TARGET_STRING);
+ }
+ if (!empty($this->request['get']['success'])) {
+ $success = EscapeHelper::escape($this->request['get']['success'], EscapeHelper::TARGET_STRING);
+ }
+ $error = new ErrorModel();
+ if ($isNew == "true") {
+ $title = EscapeHelper::escape($this->request['post']['title'], EscapeHelper::TARGET_STRING);
+ $content = EscapeHelper::escape($this->request['post']['content'], EscapeHelper::TARGET_STRING);
+ if (!empty($title) && strlen($title) > 50) {
+ $error->addErrorField("title", "error_maintenance_settings_size_title");
+ }
+ if (!empty($content) && strlen($content) > 255) {
+ $error->addErrorField("content", "error_maintenance_settings_size_content");
+ }
+ if ($error->hasError()) {
+ $this->view->assign("content", $content);
+ $this->view->assign("title", $title);
+ } else {
+ $statusTitle = $this->configDao->update($this->confModeKeyTitle, $title);
+ $statusSubtitle = $this->configDao->update($this->confModeKeySubtitle, $content);
+
+ if ($statusSubtitle && $statusTitle) {
+ $targetLocation = APP_URL . "?mapping=admin/settings/maintenance&success=save";
+ header("Location: $targetLocation");
+ } else {
+ $error->addErrorField("maintenance", $this->messageResolver->getMessage("error_maintenance_settings_db"));
+ $this->view->assign("content", $content);
+ $this->view->assign("title", $title);
+ }
+ }
+ } else {
+ $config = $this->configDao->getAll();
+ $this->view->assign("title", $config[$this->confModeKeyTitle]);
+ $this->view->assign("content", $config[$this->confModeKeySubtitle]);
+ }
+ if ($success == "save") {
+ $this->view->assign("changemaintenance", $this->messageResolver->getMessage("maintenance_settings_save"));
+ } else if ($success == "on") {
+ $this->view->assign("changemaintenance", $this->messageResolver->getMessage("maintenance_settings_on"));
+ } else if ($success == "off") {
+ $this->view->assign("changemaintenance", $this->messageResolver->getMessage("maintenance_settings_off"));
+ } else {
+ $this->view->assign("changemaintenance", false);
+ }
+ $this->view->assign("modeStatus", $config[$this->confModeKeyMaintenance]);
+ $this->view->assign("error", $error);
+ }
+
+ public function display() {
+ $this->view->setTemplate("backend_maintenance_settings");
+ $this->view->assign("messageResolver", $this->messageResolver);
+ return $this->view->loadTemplate();
+ }
+
+}
diff --git a/app/classes/controller/ControllerMaintenanceSwitch.php b/app/classes/controller/ControllerMaintenanceSwitch.php
new file mode 100644
index 0000000..403cc84
--- /dev/null
+++ b/app/classes/controller/ControllerMaintenanceSwitch.php
@@ -0,0 +1,29 @@
+ configDao = new ConfigDao($jdbcTemplate);
+ $this ->status = $status;
+ }
+
+ public function process() {
+ if($this->status == 1) {
+ $statusTitle = $this -> configDao -> update($this->confModeKeyMaintenance,"true");
+ } else if($this->status == 0) {
+ $statusTitle = $this -> configDao -> update($this->confModeKeyMaintenance,"false");
+ }
+ $targetLocation = APP_URL . "?mapping=admin/settings/maintenance&success=".($this ->status == 1 ? "on" : "").($this ->status == 0 ? "off" : "");
+ header("Location: $targetLocation");
+ }
+
+ public function display() {
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerPresentDetailView.php b/app/classes/controller/ControllerPresentDetailView.php
new file mode 100644
index 0000000..94c2860
--- /dev/null
+++ b/app/classes/controller/ControllerPresentDetailView.php
@@ -0,0 +1,38 @@
+view = new FrontendView();
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->presentDao = new PresentDao($jdbcTemplate);
+ $this->appDebugger = AppFactory::getDebugger(IS_DEBUG);
+ }
+
+ public function process() {
+ $isError = false;
+ if (!empty($this->request['get']['presentId'])) {
+ $presentId = EscapeHelper::escape($this->request['get']['presentId'], EscapeHelper::TARGET_NUMBER);
+ $present = $this->presentDao->getById($presentId);
+ $this->view->assign("present", $present);
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_parameter_error"));
+ }
+ $this->view->assign("isError", $isError);
+ }
+
+ public function display() {
+ $this->view->setTemplate("detailview");
+ $this->view->assign("messageResolver", $this->messageResolver);
+ return $this->view->loadTemplate();
+ }
+
+}
diff --git a/app/classes/controller/ControllerPresentShare.php b/app/classes/controller/ControllerPresentShare.php
new file mode 100644
index 0000000..b02bfb6
--- /dev/null
+++ b/app/classes/controller/ControllerPresentShare.php
@@ -0,0 +1,104 @@
+view = new AjaxView();
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->presentDao = new PresentDao($jdbcTemplate);
+ }
+
+ public function process() {
+ $presentId = EscapeHelper::escape($this->request['post']['presentId'], EscapeHelper::TARGET_NUMBER);
+ $emailFrom = EscapeHelper::escape($this->request['post']['emailfrom'], EscapeHelper::TARGET_STRING);
+ $emailTo = EscapeHelper::escape($this->request['post']['emailto'], EscapeHelper::TARGET_STRING);
+ $nameFrom = EscapeHelper::escape($this->request['post']['namefrom'], EscapeHelper::TARGET_STRING);
+ $nameTo = EscapeHelper::escape($this->request['post']['nameto'], EscapeHelper::TARGET_STRING);
+ $content = EscapeHelper::escape($this->request['post']['content'], EscapeHelper::TARGET_STRING);
+ $error = new ErrorModel();
+ if (HelperUtil::isNullOrEmptyString($emailFrom) && !filter_var($emailFrom, FILTER_VALIDATE_EMAIL)) {
+ $error->addErrorField("emailfrom", "error_share_emailfrom");
+ }
+ if (HelperUtil::isNullOrEmptyString($emailTo)) {
+ $error->addErrorField("emailto", "error_share_emailto");
+ } else if (!filter_var($emailTo, FILTER_VALIDATE_EMAIL)) {
+ $to = explode(';', $emailTo);
+ foreach ($to as $toMailAddress) {
+ if (!filter_var($toMailAddress, FILTER_VALIDATE_EMAIL)) {
+ $error->addErrorField("emailto", "error_share_emailto");
+ }
+ }
+ }
+ if (HelperUtil::isNullOrEmptyString($nameFrom)) {
+ $error->addErrorField("namefrom", "error_share_namefrom");
+ }
+ $present = null;
+ if (empty($presentId)) {
+ $error->addErrorField("content", "error_share_presentId");
+ } else {
+ $present = $this->presentDao->getById($presentId);
+ if ($present == null) {
+ $error->addErrorField("content", "error_share_presentId");
+ }
+ }
+ if ($error->hasError()) {
+ $this->view->assign("emailfrom", $emailFrom);
+ $this->view->assign("presentId", $presentId);
+ $this->view->assign("emailto", $emailTo);
+ $this->view->assign("namefrom", $nameFrom);
+ $this->view->assign("nameto", $nameTo);
+ $this->view->assign("content", $content);
+ } else {
+ $this->sendEmailUsePresent($emailTo, $emailFrom, $content, $nameFrom, $nameTo, $present);
+ $this->success = true;
+ }
+ $this->view->assign("error", $error);
+ }
+
+ public function display() {
+ if ($this->success) {
+ $this->view->setTemplate("share_success");
+ } else {
+ $this->view->setTemplate("share_modal");
+ }
+ $this->view->assign("messageResolver", $this->messageResolver);
+ return $this->view->loadTemplate();
+ }
+
+ /**
+ *
+ * @param type $to
+ * @param type $from
+ * @param type $content
+ * @param type $nameFrom
+ * @param type $nameTo
+ * @param PresentModel $present
+ */
+ private function sendEmailUsePresent($to, $from, $content, $nameFrom, $nameTo, PresentModel $present) {
+ $toAddresses = explode(';', $to);
+ $mailTemplate = new MailTemplate("emailshare", AppFactory::getTemplateEngine(TEMPLATE_PATH));
+ $url = APP_URL . "?mapping=present/view&presentId=" . $present->getId();
+ $info = $this->messageResolver->getMessage("email_share_present_info") . APP_NAME;
+ $subject = "[" . APP_ABBREVIATION . "]" . $this->messageResolver->getMessage("email_share_present_subject", array($nameFrom, $present->getTitle()));
+ if (!HelperUtil::isNullOrEmptyString($nameTo)) {
+ $salutation = $this->messageResolver->getMessage("email_share_present_toName") . " " . $nameTo . ",";
+ } else {
+ $salutation = $this->messageResolver->getMessage("email_share_present_toName") . ",";
+ }
+ $mailTemplate->assign("text", $this->messageResolver->getMessage("email_share_present_text_html", array($nameFrom, $present->getTitle(), $url, APP_NAME)) . "
" . $content);
+ $mailTemplate->assign("salutation", $salutation);
+ $mailTemplate->assign("info", $info);
+ $text = $salutation . "\n" . $this->messageResolver->getMessage("email_share_present_text", array($nameFrom, $present->getTitle(), $url, APP_NAME)) . "\n\n" . $content . "\n\n" . $info;
+ foreach ($toAddresses as $toAddress) {
+ HelperUtil::sendEmail($toAddress, $from, $from, $mailTemplate->getHtml(), $text, $subject);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerProfile.php b/app/classes/controller/ControllerProfile.php
new file mode 100644
index 0000000..2bf7339
--- /dev/null
+++ b/app/classes/controller/ControllerProfile.php
@@ -0,0 +1,53 @@
+view = new BackendView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->login = $login;
+ }
+
+ public function process() {
+ $isEdit = false;
+ if (filter_has_var(INPUT_POST, "profil_data")) {
+ $this->login->processEditProfil();
+ $isEdit = true;
+ }
+ if (filter_has_var(INPUT_POST, "profil_password")) {
+ $this->login->processEditPassword();
+ $isEdit = true;
+ }
+ $login = $this->login->getProfilViewVars();
+ if ($isEdit && !$login['login']->errors) {
+ $_SESSION['profil_messages'] = $login['login']->messages;
+ $targetLocation = APP_URL . "?mapping=user/profile&success=save";
+ header("Location: $targetLocation");
+ }
+ }
+
+ public function display() {
+ if (filter_has_var(INPUT_GET, "success")) {
+ $messages = $_SESSION['profil_messages'];
+ $this->view->assign("messages", $messages);
+ unset($messages);
+ $_SESSION['profil_messages'] = null;
+ } else {
+ $this->view->assign("messages", null);
+ }
+ $this->view->setTemplate($this->login->getProfilView());
+ $this->view->assign("messageResolver", $this->messageResolver);
+ $this->view->assign($this->login->getProfilViewVars());
+ $security = $this->login->getSecurityModel();
+ $this->view->assign("username", $security->getUserName());
+ $this->view->assign("email", $security->getEmail());
+ return $this->view->loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerRegister.php b/app/classes/controller/ControllerRegister.php
new file mode 100644
index 0000000..a4171af
--- /dev/null
+++ b/app/classes/controller/ControllerRegister.php
@@ -0,0 +1,31 @@
+view = new BackendView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->login = $login;
+ }
+
+ public function process() {
+ if (!isset($this->request["post"]["register"]) && isset($this->request["get"]["id"]) && isset($this->request["get"]["verification_code"])) {
+ $this->login->processRegister();
+ }
+ }
+
+ public function display() {
+ $this->view->setTemplate($this->login->getRegisterView());
+ $this->view->assign("messageResolver", $this->messageResolver);
+ $this->view->assign($this->login->getRegisterViewVars());
+ $this->view->assign("isRegisterConfirm", true);
+ return $this->view->loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerReleasePresent.php b/app/classes/controller/ControllerReleasePresent.php
new file mode 100644
index 0000000..5e9bc6d
--- /dev/null
+++ b/app/classes/controller/ControllerReleasePresent.php
@@ -0,0 +1,90 @@
+view = new FrontendView();
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->presentDao = new PresentDao($jdbcTemplate);
+ $this->appLogger = AppFactory::getLogger(LOG_MODE);
+ $this->appDebugger = AppFactory::getDebugger(IS_DEBUG);
+ }
+
+ public function process() {
+ $success = null;
+ $isError = false;
+ $isForm = false;
+ if (!empty($this->request['get']['success'])) {
+ $success = EscapeHelper::escape($this->request['get']['success'], EscapeHelper::TARGET_STRING);
+ }
+ if (!empty($success) && $success == "view") {
+ $args = EscapeHelper::escape($this->request['get']['args'], EscapeHelper::TARGET_STRING);
+ $parameter = base64_decode($args);
+ $presentId = EscapeHelper::escape(str_replace("presentId=", "", $parameter), EscapeHelper::TARGET_NUMBER);
+ $present = $this->presentDao->getById($presentId);
+ if ($present != null) {
+ $this->view->assign("present", $present);
+ $this->view->assign("isSuccess", true);
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_notfound_present"));
+ }
+ } else {
+ $releaseCode = null;
+ $releaseButton = null;
+ if (!empty($this->request['post']['releasecode'])) {
+ $releaseCode = EscapeHelper::escape($this->request['post']['releasecode'], EscapeHelper::TARGET_STRING);
+ }
+ if (!empty($this->request['post']['releasebutton'])) {
+ $releaseButton = EscapeHelper::escape($this->request['post']['releasebutton'], EscapeHelper::TARGET_STRING);
+ }
+ if (!empty($releaseCode) && !empty($releaseButton)) {
+ $present = $this->presentDao->getByCode($releaseCode);
+ if ($present != null) {
+ $this->presentDao->releasePresent($present->getId());
+ $this->appLogger->info('Das Geschenk ' . $present->getId() . ' wurde wieder freigegeben.');
+ $targetLocation = APP_URL . "?success=view&args=" . base64_encode("presentId=$present -> getId()");
+ header("Location: $targetLocation");
+ }
+ } else {
+ $releaseCode = null;
+ if (!empty($this->request['get']['releasecode'])) {
+ $releaseCode = EscapeHelper::escape($this->request['get']['releasecode'], EscapeHelper::TARGET_STRING);
+ }
+ if (!empty($releaseCode)) {
+ $this->appDebugger->debug($releaseCode);
+ $present = $this->presentDao->getByCode($releaseCode);
+ $this->appDebugger->debug($present);
+ if ($present != null) {
+ $this->view->assign("present", $present);
+ $this->view->assign("isView", true);
+ $this->view->assign("releasebutton", rand(0, 99) . rand(0, 99) . rand(0, 99) . rand(0, 99));
+ $this->view->assign("releasecode", $releaseCode);
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_notfound_present"));
+ }
+ } else {
+ $isForm = true;
+ }
+ }
+ }
+ $this->view->assign("isForm", $isForm);
+ $this->view->assign("isError", $isError);
+ }
+
+ public function display() {
+ $this->view->setTemplate("releasepresent");
+ $this->view->assign("messageResolver", $this->messageResolver);
+ return $this->view->loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerResetPassword.php b/app/classes/controller/ControllerResetPassword.php
new file mode 100644
index 0000000..34a5341
--- /dev/null
+++ b/app/classes/controller/ControllerResetPassword.php
@@ -0,0 +1,42 @@
+view = new AjaxView(TEMPLATE_PATH_BACKEND);
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->login = $login;
+ }
+
+ public function process() {
+ $isSuccess = false;
+ if (filter_input(INPUT_POST, "request_password_reset") != null && filter_input(INPUT_POST, "user_name") != null) {
+ $isSuccess = $this->login->setPasswordResetDatabaseTokenAndSendMail();
+ } else if (filter_input(INPUT_POST, "submit_new_password") != null) {
+ $isSuccess = $this->login->editNewPassword();
+ } else if (filter_input(INPUT_GET, "user_name") != null && filter_input(INPUT_GET, "verification_code") != null) {
+ $this->login->checkIfEmailVerificationCodeIsValid();
+ }
+ $this->view->assign("isSuccess", $isSuccess);
+ }
+
+ public function display() {
+ if ($this->login->resetLinkIsValid()) {
+ $this->view->setTemplate($this->login->getResetConfirmView());
+ $this->view->assign("userName", $this->request["get"]["user_name"]);
+ $this->view->assign("verificationCode", $this->request["get"]["verification_code"]);
+ } else {
+ $this->view->setTemplate($this->login->getResetView());
+ }
+ $this->view->assign("messageResolver", $this->messageResolver);
+ $this->view->assign($this->login->getProfilViewVars());
+ return $this->view->loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerSettings.php b/app/classes/controller/ControllerSettings.php
new file mode 100644
index 0000000..4539e4a
--- /dev/null
+++ b/app/classes/controller/ControllerSettings.php
@@ -0,0 +1,119 @@
+view = new BackendView($login->getSecurityModel());
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->configDao = new ConfigDao($jdbcTemplate);
+ }
+
+ public function process() {
+ $isNew = null;
+ $success = null;
+ if (!empty($this->request['post']['checknew'])) {
+ $isNew = EscapeHelper::escape($this->request['post']['checknew'], EscapeHelper::TARGET_STRING);
+ }
+ if (!empty($this->request['get']['success'])) {
+ $success = EscapeHelper::escape($this->request['get']['success'], EscapeHelper::TARGET_STRING);
+ }
+ $error = new ErrorModel();
+ if ($isNew == "true") {
+ $logmode = EscapeHelper::escape($this->request['post']['logmode'], EscapeHelper::TARGET_STRING);
+ $domainUrl = EscapeHelper::escape($this->request['post']['domainurl'], EscapeHelper::TARGET_STRING);
+ $template = EscapeHelper::escape($this->request['post']['template'], EscapeHelper::TARGET_STRING);
+ $emailAddress = EscapeHelper::escape($this->request['post']['emailaddress'], EscapeHelper::TARGET_STRING);
+ $codelength = EscapeHelper::escape($this->request['post']['codelength'], EscapeHelper::TARGET_STRING);
+ $appname = EscapeHelper::escape($this->request['post']['appname'], EscapeHelper::TARGET_STRING);
+ $appabbreviation = EscapeHelper::escape($this->request['post']['appabbreviation'], EscapeHelper::TARGET_STRING);
+ if (!filter_var($emailAddress, FILTER_VALIDATE_EMAIL) || HelperUtil::isNullOrEmptyString($emailAddress)) {
+ $error->addErrorField("emailaddress", "error_settings_email");
+ }
+ if (!filter_var($domainUrl, FILTER_VALIDATE_URL) || HelperUtil::isNullOrEmptyString($domainUrl)) {
+ $error->addErrorField("domainurl", "error_settings_url");
+ }
+ if (HelperUtil::isNullOrEmptyString($appname)) {
+ $error->addErrorField("appname", "error_settings_appname");
+ }
+ if (HelperUtil::isNullOrEmptyString($appabbreviation)) {
+ $error->addErrorField("appabbreviation", "error_settings_appabbreviation");
+ }
+ $isLogModeMatch = false;
+ $isTemplateMatch = false;
+ foreach ($this->logModeArray as $key => $value) {
+ if ($logmode == $value) {
+ $isLogModeMatch = true;
+ }
+ }
+ if (!$isLogModeMatch) {
+ $error->addErrorField("logmode", "error_settings_logmode");
+ }
+ foreach ($this->templateArray as $key => $value) {
+ if ($template == $value) {
+ $isTemplateMatch = true;
+ }
+ }
+ if (!$isTemplateMatch) {
+ $error->addErrorField("template", "error_settings_template");
+ }
+ if ($error->hasError()) {
+ $this->view->assign("template", $template);
+ $this->view->assign("logmode", $logmode);
+ $this->view->assign("codelength", $codelength);
+ $this->view->assign("emailaddress", $emailAddress);
+ $this->view->assign("domainurl", $domainUrl);
+ $this->view->assign("appname", $appname);
+ $this->view->assign("appabbreviation", $appabbreviation);
+ } else {
+ $this->configDao->update($this->confModeKeyCodeLength, $codelength);
+ $this->configDao->update($this->confModeKeyUrl, $domainUrl);
+ $this->configDao->update($this->confModeKeyEmailAddress, $emailAddress);
+ $this->configDao->update($this->confModeKeyLogMode, $logmode);
+ $this->configDao->update($this->confModeKeyTemplate, $template);
+ $this->configDao->update($this->confModeKeyAppAbbreviation, $appabbreviation);
+ $this->configDao->update($this->confModeKeyAppName, $appname);
+ $targetLocation = APP_URL . "?mapping=admin/settings/all&success=save";
+ header("Location: $targetLocation");
+ }
+ } else {
+ $config = $this->configDao->getAll();
+ $this->view->assign("logmode", $config[$this->confModeKeyLogMode]);
+ $this->view->assign("codelength", $config[$this->confModeKeyCodeLength]);
+ $this->view->assign("emailaddress", $config[$this->confModeKeyEmailAddress]);
+ $this->view->assign("template", $config[$this->confModeKeyTemplate]);
+ $this->view->assign("domainurl", $config[$this->confModeKeyUrl]);
+ $this->view->assign("appname", $config[$this->confModeKeyAppName]);
+ $this->view->assign("appabbreviation", $config[$this->confModeKeyAppAbbreviation]);
+ }
+ if (isset($success) && $success == "save") {
+ $this->view->assign("changesettings", $this->messageResolver->getMessage("settings_save"));
+ } else {
+ $this->view->assign("changesettings", false);
+ }
+ $this->view->assign("error", $error);
+ $this->view->assign("logmodes", $this->logModeArray);
+ $this->view->assign("templates", $this->templateArray);
+ }
+
+ public function display() {
+ $this->view->setTemplate("backend_settings");
+ $this->view->assign("messageResolver", $this->messageResolver);
+ return $this->view->loadTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/ControllerStartpage.php b/app/classes/controller/ControllerStartpage.php
new file mode 100644
index 0000000..c3baefb
--- /dev/null
+++ b/app/classes/controller/ControllerStartpage.php
@@ -0,0 +1,43 @@
+view = new FrontendView();
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->presentDao = new PresentDao($jdbcTemplate);
+ }
+
+ public function process() {
+ $view = null;
+ if (!empty($this->request['get']['view'])) {
+ $view = EscapeHelper::escape($this->request['get']['view'], EscapeHelper::TARGET_STRING);
+ }
+ if ($view == "grid") {
+ $this->view->assign("view", "grid");
+ } else {
+ $this->view->assign("view", "list");
+ }
+ $presentlist = $this->presentDao->getAllFreePresents();
+ $this->view->assign("presents", $presentlist->getItems());
+ $this->view->assign("error", new ErrorModel());
+ }
+
+ public function display() {
+ $this->view->setTemplate("presenttable");
+ $this->view->assign("messageResolver", $this->messageResolver);
+ $this->view->assign("emailfrom", "");
+ $this->view->assign("namefrom", "");
+ $this->view->assign("emailto", "");
+ $this->view->assign("nameto", "");
+ $this->view->assign("content", "");
+ return $this->view->loadTemplate();
+ }
+
+}
diff --git a/app/classes/controller/ControllerUsePresent.php b/app/classes/controller/ControllerUsePresent.php
new file mode 100644
index 0000000..2c0d4f4
--- /dev/null
+++ b/app/classes/controller/ControllerUsePresent.php
@@ -0,0 +1,134 @@
+view = new FrontendView();
+ $this->request = $request;
+ $this->messageResolver = AppFactory::getMessageResolver();
+ $this->presentDao = new PresentDao($jdbcTemplate);
+ $this->appDebugger = AppFactory::getDebugger(IS_DEBUG);
+ }
+
+ public function process() {
+ //VIEW or Process
+ $success = null;
+ $isError = false;
+ if (!empty($this->request['get']['success'])) {
+ $success = EscapeHelper::escape($this->request['get']['success'], EscapeHelper::TARGET_STRING);
+ }
+ if (!empty($success) && $success == "view") {
+ $args = EscapeHelper::escape($this->request['get']['args'], EscapeHelper::TARGET_STRING);
+ $parameter = base64_decode($args);
+ list($parameterCode, $parameterId) = split("&", $parameter);
+ $presentId = EscapeHelper::escape(str_replace("presentId=", "", $parameterId), EscapeHelper::TARGET_NUMBER);
+ $code = EscapeHelper::escape(str_replace("code=", "", $parameterCode), EscapeHelper::TARGET_STRING);
+ if (!empty($presentId) && !empty($code)) {
+ $present = $this->presentDao->getById($presentId);
+ if ($present->getCode() == $code) {
+ $this->view->assign("present", $present);
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_parameter_error"));
+ }
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_parameter_error"));
+ }
+ } else {
+ $presentId = EscapeHelper::escape($this->request['post']['presentId'], EscapeHelper::TARGET_NUMBER);
+ $email = null;
+ $isError = false;
+ $code = "";
+ $emailInput = $this->request['post']['email'];
+ if (!empty($emailInput)) {
+ $this->appDebugger->debug($emailInput);
+ $emailInput = EscapeHelper::escape($emailInput, EscapeHelper::TARGET_STRING);
+ if (!empty($emailInput) && $emailInput != "" && HelperUtil::checkEmailAddress($emailInput)) {
+ $email = $emailInput;
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_validate_email"));
+ }
+ }
+ $this->appDebugger->trace();
+ $this->appDebugger->debug($presentId);
+ $this->appDebugger->debug($email);
+ if (!$isError) {
+ if (!empty($presentId) && $presentId > 0) {
+ $present = $this->presentDao->getById($presentId);
+ $this->appDebugger->debug($present);
+ if ($present != NULL && $present->getCode() == null) {
+ $generateCode = "";
+ do {
+ $generateCode = $this->getCodeValue();
+ } while ($this->presentDao->existCode($generateCode));
+
+ if ($this->presentDao->usePresent($presentId, $generateCode)) {
+ $this->view->assign("code", $generateCode);
+ $code = $generateCode;
+ if (!empty($email)) {
+ if (!$this->sendEmailUsePresent($email, $present, $generateCode)) {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_send_email"));
+ }
+ }
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_update_present_db"));
+ }
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_notfound_present"));
+ }
+ } else {
+ $isError = true;
+ $this->view->assign("error", $this->messageResolver->getMessage("error_empty_presentId"));
+ }
+ }
+ if (!$isError) {
+ $targetLocation = APP_URL . "?mapping=present/waehlen&success=view&args=" . base64_encode("code=$code&presentId=$presentId");
+ header("Location: $targetLocation");
+ }
+ }
+ $this->view->assign("isError", $isError);
+ }
+
+ public function display() {
+ $this->view->setTemplate("usepresent");
+ $this->view->assign("messageResolver", $this->messageResolver);
+ return $this->view->loadTemplate();
+ }
+
+ private function getCodeValue() {
+ $signs = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'U', 'V', 'W', 'X', 'Y', 'Z', '$', '%', '/', '(', '_', '-', ';', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0');
+ $int_array = count($signs);
+ $dates = array(date("Hmsdi"), date("Hdims"), date("msHdi"));
+ $code = hash("crc32b", $dates[rand(0, count($dates) - 1)] . rand(0, 99));
+ for ($i = 0; $i < PRESENT_CODE_LENGTH_ADD; $i++) {
+ $code .= $signs[rand(0, $int_array - 1)];
+ }
+ return $code;
+ }
+
+ private function sendEmailUsePresent($to, PresentModel $present, $code) {
+ $mailTemplate = new MailTemplate("emailusepresent", AppFactory::getTemplateEngine(TEMPLATE_PATH));
+ $url = APP_URL . "?mapping=present/release&releasecode=$code";
+ $viewUrl = APP_URL . "?mapping=present/view&presentId=" . $present->getId();
+ $salutation = $this->messageResolver->getMessage("email_use_present_salutation") . APP_NAME;
+ $info = $this->messageResolver->getMessage("email_use_present_info");
+ $subject = APP_ABBREVIATION . $this->messageResolver->getMessage("email_use_present_subject");
+ $mailTemplate->assign("text", $this->messageResolver->getMessage("email_use_present_text_html", array($present->getTitle(), $url, $viewUrl)));
+ $mailTemplate->assign("salutation", $salutation);
+ $mailTemplate->assign("info", $info);
+ $text = $salutation . "\n" . $this->messageResolver->getMessage("email_use_present_text", array($present->getTitle(), $url, $viewUrl)) . "\n\n" . $info;
+ return HelperUtil::sendEmail($to, PRESENT_EMAIL_FROM, PRESENT_EMAIL_REPLY, $mailTemplate->getHtml(), $text, $subject);
+ }
+
+}
\ No newline at end of file
diff --git a/app/classes/controller/index.html b/app/classes/controller/index.html
new file mode 100644
index 0000000..c942a79
--- /dev/null
+++ b/app/classes/controller/index.html
@@ -0,0 +1,10 @@
+
+
Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/classes/dao/ConfigDao.php b/app/classes/dao/ConfigDao.php new file mode 100644 index 0000000..70f858e --- /dev/null +++ b/app/classes/dao/ConfigDao.php @@ -0,0 +1,43 @@ + jdbcTemplate = $jdbcTemplate; + } + + public function getAll() { + $tableDatas = $this -> jdbcTemplate -> selectColumn($this -> tableName, $this->allColumns); + $conf = array(); + foreach ($tableDatas as $data) { + $conf[$data["key"]] = $data["value"]; + } + return $conf; + } + + public function getByKey($key) { + return $this -> jdbcTemplate ->getByUnique($this->tableName, self::COLUMN_VALUE, array(self::COLUMN_KEY => $key)); + } + + public function update($key,$value) { + if($this -> jdbcTemplate -> isTrue($this->tableName, array(self::COLUMN_KEY => "$key"))) { + $data = $this -> jdbcTemplate ->update($this->tableName, array(self::COLUMN_VALUE => $value), array(self::COLUMN_KEY => $key)); + } else { + $id = $this -> jdbcTemplate ->insert($this->tableName, array(self::COLUMN_VALUE => $value,self::COLUMN_KEY => $key)); + } + return true; + } + +} +?> \ No newline at end of file diff --git a/app/classes/dao/PresentDao.php b/app/classes/dao/PresentDao.php new file mode 100644 index 0000000..d113a95 --- /dev/null +++ b/app/classes/dao/PresentDao.php @@ -0,0 +1,113 @@ + jdbcTemplate = $jdbcTemplate; + } + + public function getAll() { + $tableDatas = $this -> jdbcTemplate -> selectColumn($this -> tableName, $this->allColumns); + $c = new Collection(); + foreach ($tableDatas as $data) { + $c->addItem(new PresentModel($data),$data['id']); + } + return $c; + } + + public function getAllFreePresents() { + $tableDatas = $this -> jdbcTemplate -> selectColumnConditions($this -> tableName, $this->allColumns, array(self::COLUMN_STATUS => self::PRESENT_STATUS_NOTUSE)); + $c = new Collection(); + foreach ($tableDatas as $data) { + $c->addItem(new PresentModel($data),$data['id']); + } + return $c; + } + + public function existCode($code) { + return $this -> jdbcTemplate -> isTrue($this->tableName, array(self::COLUMN_CODE => "$code")); + } + + public function getById($presentId) { + $returnValue = null; + $data = $this -> jdbcTemplate ->getByUnique($this->tableName, $this->allColumns, array(self::COLUMN_ID => $presentId)); + if(!empty($data)) { + $returnValue = new PresentModel($data); + } + return $returnValue; + } + + public function update(PresentModel $present) { + $returnValue = null; + $data = $this -> jdbcTemplate ->update($this->tableName, array(self::COLUMN_EDIT_DATE => date("Y-m-d H:i:s"),self::COLUMN_DESCRIPTION => $present->getDescription(), self::COLUMN_IMAGEPATH => $present->getImagePath(), self::COLUMN_TITLE=>$present->getTitle(),self::COLUMN_LINKS=>$present->getLinks()), array(self::COLUMN_ID => $present->getId())); + if($data == 1){ + $returnValue = $present->getId(); + } + return $returnValue; + } + + public function delete($presentId) { + $returnValue = null; + $data = $this -> jdbcTemplate ->delete($this->tableName, array(self::COLUMN_ID => $presentId)); + if($data == 1){ + $returnValue = $presentId; + } + return $returnValue; + } + + public function getByCode($code) { + $returnValue = null; + $data = $this -> jdbcTemplate ->getByUnique($this->tableName, $this->allColumns, array("AND" => array(self::COLUMN_CODE => $code, self::COLUMN_STATUS => self::PRESENT_STATUS_USE))); + if(!empty($data)) { + $returnValue = new PresentModel($data); + } + return $returnValue; + } + + public function usePresent($presentId, $code) { + $status = self::PRESENT_STATUS_USE; + $rows = $this -> jdbcTemplate ->update($this->tableName, array(self::COLUMN_CODE=>$code,self::COLUMN_STATUS => $status), array(self::COLUMN_ID => $presentId)); + if($rows != 1) { + return false; + } else { + return true; + } + } + + public function releasePresent($presentId) { + $status = self::PRESENT_STATUS_NOTUSE; + $rows = $this -> jdbcTemplate ->update($this->tableName, array(self::COLUMN_EDIT_DATE => date("Y-m-d H:i:s"),self::COLUMN_CODE=>null,self::COLUMN_STATUS => $status), array(self::COLUMN_ID => $presentId)); + if($rows != 1) { + return false; + } else { + return true; + } + } + + public function createPresent(PresentModel $present) { + $id = $this -> jdbcTemplate ->insert($this->tableName, array(self::COLUMN_EDIT_DATE => date("Y-m-d H:i:s"),self::COLUMN_DESCRIPTION => $present->getDescription(), self::COLUMN_IMAGEPATH => $present->getImagePath(), self::COLUMN_TITLE=>$present->getTitle(),self::COLUMN_LINKS=>$present->getLinks(),self::COLUMN_STATUS=>PRESENT_STATUS_NOTUSE)); + return $id; + } + + +} +?> \ No newline at end of file diff --git a/app/classes/dao/index.html b/app/classes/dao/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/app/classes/dao/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/classes/index.html b/app/classes/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/app/classes/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/classes/loader.php b/app/classes/loader.php new file mode 100644 index 0000000..556f803 --- /dev/null +++ b/app/classes/loader.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/app/classes/model/errorModel.php b/app/classes/model/errorModel.php new file mode 100644 index 0000000..c7e0bdc --- /dev/null +++ b/app/classes/model/errorModel.php @@ -0,0 +1,35 @@ +errorFields = array(); + $this->errorFieldMessage = array(); + } + + public function addErrorField($field, $msg) { + $this->errorFields[] = $field; + $this->errorFieldMessage[$field] = $msg; + $this->isError = true; + } + + public function hasErrors($field) { + foreach ($this->errorFields as $key => $value) { + if($value == $field) { + return true; + } + } + return false; + } + + public function getMessage($field) { + return $this->errorFieldMessage[$field]; + } + + public function hasError(){ + return $this->isError ; + } + +} diff --git a/app/classes/model/index.html b/app/classes/model/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/app/classes/model/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/classes/model/presentModel.php b/app/classes/model/presentModel.php new file mode 100644 index 0000000..5b2cea2 --- /dev/null +++ b/app/classes/model/presentModel.php @@ -0,0 +1,100 @@ + id = $dic[PresentDao::COLUMN_ID]; + $this -> title = $dic[PresentDao::COLUMN_TITLE]; + $this -> imagePath = $dic[PresentDao::COLUMN_IMAGEPATH]; + $this -> description = $dic[PresentDao::COLUMN_DESCRIPTION]; + $this -> status = $dic[PresentDao::COLUMN_STATUS]; + $this -> code = $dic[PresentDao::COLUMN_CODE]; + $this -> links = unserialize($dic[PresentDao::COLUMN_LINKS]); + } + } + + public function getId() { + return $this -> id; + } + + public function getTitle() { + return $this -> title; + } + + public function getImagePath() { + return $this -> imagePath; + } + + public function getDescription() { + return $this -> description; + } + + public function getStatus() { + return $this -> status; + } + + public function getCode() { + return $this -> code; + } + + public function getLinks() { + return $this -> links; + } + + public function setId($id) { + $this -> id = $id; + } + + public function setTitle($title) { + $this -> title = $title; + } + + public function setImagePath($imagePath) { + $this -> imagePath = $imagePath; + } + + public function isImage() { + return filter_var( $this -> imagePath, FILTER_VALIDATE_URL); + } + + public function setDescription($description) { + $this -> description = $description; + } + + public function setCode($code) { + $this -> code = $code; + } + + public function setStatus($status) { + $this -> status = $status; + } + + public function setLinks($links) { + $this -> links = $links; + } + + public function __toString() { + return "ID:$this->id -- Titel: '$this->titel' -- Status: ' $this->status'"; + } + + public function getDetails() { + $ausgabe = '' . $this -> getTitle() . '
+' . $this -> getDescription() . ' +
'; + $split_result = split(';', $this -> getLinks()); + $out_link = ""; + foreach ($split_result as $link) { + $out_link .= '' . $link . '' . $out_link . '
'; + return $ausgabe; + } + +} diff --git a/app/classes/model/securityModel.php b/app/classes/model/securityModel.php new file mode 100644 index 0000000..464d87c --- /dev/null +++ b/app/classes/model/securityModel.php @@ -0,0 +1,42 @@ +signIn = $signIn; + $this->userName = $userName; + $this->roles = $roles; + $this->email = $email; + } + + function isSignIn() { + if($this->signIn != null) { + return $this->signIn; + } + return false; + } + + function getUserName() { + return $this->userName; + } + + function getRoles() { + return $this->roles; + } + + function getEmail() { + return $this->email; + } + +} diff --git a/app/classes/routeFactory.php b/app/classes/routeFactory.php new file mode 100644 index 0000000..9f6642a --- /dev/null +++ b/app/classes/routeFactory.php @@ -0,0 +1,92 @@ + "ControllerCreateEditPresent", + "admin/present/edit" => "ControllerCreateEditPresent", + "admin/present/delete" => "ControllerDeletePresent", + "admin/settings/maintenance" => "ControllerMaintenanceSettings", + "admin" => "ControllerAdminStartpage", + "admin/settings/all" => "ControllerSettings", + "user/create" => "ControllerCreateUser", + "user/profile" => "ControllerProfile", + ); + private $defaultController = array("present/waehlen" => "ControllerUsePresent", + "present/share" => "ControllerPresentShare", + "present/release" => "ControllerReleasePresent", + "present/view" => "ControllerPresentDetailView", + "register" => "ControllerRegister", + "resetpassword" => "ControllerResetPassword", + ); + private $security; + private $login; + + function __construct() { + $this->login = new $this->securityService(); + $this->security = $this->login->getSecurityModel(); + } + + function getController($getRequest, $postRequest, $jdbcTemplate) { + $mapping = $this->getMapping($getRequest); + $request = array("get" => $getRequest, "post" => $postRequest); + if ($mapping == 'login') { + return new ControllerLogin($request, $this->login, "admin"); + } else if ($mapping == 'logout') { + return new ControllerLogout($this->login); + } + $resultController = null; + if (!array_key_exists($mapping, $this->adminController)) { + $resultController = $this->getNoLoginController($request, $mapping, $jdbcTemplate); + } else { + // We've been requested to log in + if ($this->security->isSignIn()) { + $resultController = $this->getLoginController($request, $mapping, $jdbcTemplate); + } else { + $resultController = new ControllerLogin($request, $this->login, $mapping); + } + } + if ($resultController == null) { + throw new Exception(); + } + return $resultController; + } + + private function getMapping($getRequest) { + $mapping = ""; + if (isset($getRequest['mapping'])) { + $mapping = htmlspecialchars($getRequest['mapping']); + } else if (empty($mapping) && $this->security->isSignIn()) { + $mapping = "admin"; + } + return $mapping; + } + + private function getLoginController($request, $mapping, $jdbcTemplate) { + if (array_key_exists($mapping, $this->adminController)) { + return new $this->adminController[$mapping]($request, $jdbcTemplate, $this->login); + } else if ($mapping == "admin/settings/maintenance/active") { + return new ControllerMaintenanceSwitch($jdbcTemplate, 1); + } else if ($mapping == "admin/settings/maintenance/inactive") { + return new ControllerMaintenanceSwitch($jdbcTemplate, 0); + } + } + + private function getNoLoginController($request, $mapping, $jdbcTemplate) { + if (MAINTENANCE && !$this->security->isSignIn()) { + return new ControllerMaintenance($jdbcTemplate); + } else { + if (empty($mapping)) { + return new ControllerStartpage($request, $jdbcTemplate, $this->login); + } else if (array_key_exists($mapping, $this->defaultController)) { + return new $this->defaultController[$mapping]($request, $jdbcTemplate, $this->login); + } + } + } + +} diff --git a/app/classes/view/AjaxView.php b/app/classes/view/AjaxView.php new file mode 100644 index 0000000..e9fb228 --- /dev/null +++ b/app/classes/view/AjaxView.php @@ -0,0 +1,57 @@ + template = new TemplateResolver(AppFactory::getTemplateEngine($templatePath)); + } + + /** + * Ordnet eine Variable einem bestimmten Schlüssel zu. + * + * @param String $key Schlüssel + * @param String $value Variable + */ + function assign($variable, $value = null) { + if (is_array($variable)) + $this -> templateVar += $variable; + else + $this -> templateVar[$variable] = $value; + } + + /** + * Setzt den Namen des Templates. + * + * @param String $template Name des Templates. + */ + public function setTemplate($templatePage = 'content') { + $this -> templatePage = $templatePage; + } + + /** + * Das Template-File laden und zurückgeben + * + * @param string $tpl Der Name des Template-Files (falls es nicht vorher + * über steTemplate() zugewiesen wurde). + * @return string Der Output des Templates. + */ + public function loadTemplate() { + $contentTemplate = new TemplateContentResolver($this->template, "content", $this -> templatePage); + $contentTemplate -> assign($this -> templateVar); + $layout = new TemplateGenerateLayout($contentTemplate, "ajax"); + return $layout -> getHtml(); + } + +} +?> \ No newline at end of file diff --git a/app/classes/view/BackendView.php b/app/classes/view/BackendView.php new file mode 100644 index 0000000..880b5e3 --- /dev/null +++ b/app/classes/view/BackendView.php @@ -0,0 +1,77 @@ +template = new TemplateResolver(AppFactory::getTemplateEngine(TEMPLATE_PATH_BACKEND)); + $this->security = $security; + } + + /** + * Ordnet eine Variable einem bestimmten Schlüssel zu. + * + * @param String $key Schlüssel + * @param String $value Variable + */ + function assign($variable, $value = null) { + if (is_array($variable)) + $this->templateVar += $variable; + else + $this->templateVar[$variable] = $value; + } + + /** + * Setzt den Namen des Templates. + * + * @param String $template Name des Templates. + */ + public function setTemplate($templatePage = 'content') { + $this->templatePage = $templatePage; + } + + /** + * Das Template-File laden und zurückgeben + * + * @param string $tpl Der Name des Template-Files (falls es nicht vorher + * über steTemplate() zugewiesen wurde). + * @return string Der Output des Templates. + */ + public function loadTemplate() { + $messageResolver = AppFactory::getMessageResolver(); + $contentTemplate = new TemplateContentResolver($this->template, "content", $this->templatePage); + $contentTemplate->assign($this->templateVar); + $navTemplate = new TemplateNavigationResolver($contentTemplate, "navigation", "backend_navigation"); + $navTemplate->assign("navToggle", $messageResolver->getMessage("navigation_toggle")); + $navTemplate->assign("signin", $messageResolver->getMessage("navigation_signinas") . $this->security->getUserName()); + $navTemplate->assign("messageResolver", $messageResolver); + if ($this->security->isSignIn()) { + $navTemplate->addNavItem("?mapping=admin", $messageResolver->getMessage("navigation_home_admin")); + $navTemplate->addNavItem("?mapping=admin/present/create", $messageResolver->getMessage("navigation_createpresent")); + $navTemplate->addNavItem("?mapping=admin/settings/maintenance", $messageResolver->getMessage("navigation_maintenance_settings")); + $navTemplate->addNavItem("?mapping=admin/settings/all", $messageResolver->getMessage("navigation_settings")); + $navTemplate->addNavItem("?mapping=user/create", $messageResolver->getMessage("navigation_createuser")); + } else { + $navTemplate->addNavItem("?mapping=", $messageResolver->getMessage("navigation_frontend")); + } + $headerTemplate = new TemplateHeaderResolver($navTemplate, "header", "backend_header"); + $headerTemplate->setStartpageLink(APP_URL); + $headerTemplate->setSubtitle($messageResolver->getMessage("application_subtitle")); + $layout = new TemplateGenerateLayout($headerTemplate, "backendlayout"); + $layout->assign("messageResolver", $messageResolver); + return $layout->getHtml(); + } + +} + +?> \ No newline at end of file diff --git a/app/classes/view/FrontendView.php b/app/classes/view/FrontendView.php new file mode 100644 index 0000000..a5ec155 --- /dev/null +++ b/app/classes/view/FrontendView.php @@ -0,0 +1,68 @@ + template = new TemplateResolver(AppFactory::getTemplateEngine(TEMPLATE_PATH)); + } + + /** + * Ordnet eine Variable einem bestimmten Schlüssel zu. + * + * @param String $key Schlüssel + * @param String $value Variable + */ + function assign($variable, $value = null) { + if (is_array($variable)) + $this -> templateVar += $variable; + else + $this -> templateVar[$variable] = $value; + } + + /** + * Setzt den Namen des Templates. + * + * @param String $template Name des Templates. + */ + public function setTemplate($templatePage = 'content') { + $this -> templatePage = $templatePage; + } + + /** + * Das Template-File laden und zurückgeben + * + * @param string $tpl Der Name des Template-Files (falls es nicht vorher + * über steTemplate() zugewiesen wurde). + * @return string Der Output des Templates. + */ + public function loadTemplate() { + $messageResolver = AppFactory::getMessageResolver(); + $contentTemplate = new TemplateContentResolver($this->template, "content", $this -> templatePage); + $contentTemplate -> assign($this -> templateVar); + $navTemplate = new TemplateNavigationResolver($contentTemplate, "navigation", "navigation"); + $navTemplate -> assign("navToggle",$messageResolver->getMessage("navigation_toggle")); + $navTemplate -> addNavItem("?mapping=", $messageResolver->getMessage("navigation_home")); + $navTemplate -> addNavItem("?mapping=present/release", $messageResolver->getMessage("navigation_changepresent")); + $headerTemplate = new TemplateHeaderResolver($navTemplate, "header", "header"); + $headerTemplate -> setStartpageLink(APP_URL); + $headerTemplate -> setSubtitle($messageResolver->getMessage("application_subtitle")); + $layout = new TemplateGenerateLayout($headerTemplate, "layout"); + $layout->assign("footer",$messageResolver->getMessage("application_copyright")); + $layout->assign("administrationlink","?mapping=admin"); + $layout->assign("administrationlinktext",$messageResolver->getMessage("navigation_admin")); + return $layout -> getHtml(); + } + +} +?> \ No newline at end of file diff --git a/app/classes/view/LoginView.php b/app/classes/view/LoginView.php new file mode 100644 index 0000000..304dc43 --- /dev/null +++ b/app/classes/view/LoginView.php @@ -0,0 +1,60 @@ +template = new TemplateResolver(AppFactory::getTemplateEngine(TEMPLATE_PATH_BACKEND)); + $this->security = $security; + } + + /** + * Ordnet eine Variable einem bestimmten Schlüssel zu. + * + * @param String $key Schlüssel + * @param String $value Variable + */ + function assign($variable, $value = null) { + if (is_array($variable)) { + $this->templateVar += $variable; + } else { + $this->templateVar[$variable] = $value; + } + } + + /** + * Setzt den Namen des Templates. + * + * @param String $template Name des Templates. + */ + public function setTemplate($templatePage = 'content') { + $this->templatePage = $templatePage; + } + + /** + * Das Template-File laden und zurückgeben + * + * @param string $tpl Der Name des Template-Files (falls es nicht vorher + * über steTemplate() zugewiesen wurde). + * @return string Der Output des Templates. + */ + public function loadTemplate() { + $messageResolver = AppFactory::getMessageResolver(); + $contentTemplate = new TemplateContentResolver($this->template, "content", $this->templatePage); + $contentTemplate->assign($this->templateVar); + $layout = new TemplateGenerateLayout($contentTemplate, "loginlayout"); + $layout->assign("messageResolver", $messageResolver); + return $layout->getHtml(); + } + +} diff --git a/app/config/config.inc.php b/app/config/config.inc.php new file mode 100644 index 0000000..86e5c48 --- /dev/null +++ b/app/config/config.inc.php @@ -0,0 +1,37 @@ +getAll(); + +define("APP_URL", $config['conf_domain_url']); +define("APP_VERSION", $config['conf_version']); +define("APP_URL_URL", str_replace("://","",substr(APP_URL, stripos(APP_URL, "://")))); +define("APP_DOMAIN", substr(APP_URL_URL, 0,stripos(APP_URL_URL, "/"))); +define("PRESENT_EMAIL_REPLY", $config['conf_email_address']); +define("PRESENT_EMAIL_FROM", PRESENT_EMAIL_REPLY); +define("PRESENT_CODE_LENGTH_ADD", $config['conf_code_length']); +define("LOG_MODE", ''.$config['conf_log_mode'].''); +define("TEMPLATE_STYLE", ''.$config['conf_template'].''); +define("APP_ABBREVIATION", ''.$config['conf_app_abbreviation'].''); +define("APP_NAME", ''.$config['conf_app_name'].''); + +if($config['conf_debug'] === 'false') { + define("IS_DEBUG", false);//TODO DB Config +} else { + define("IS_DEBUG", true);//TODO DB Config +} +if($config['conf_maintenance_mode'] === 'false') { + define("MAINTENANCE", false);//DB Config +} else { + define("MAINTENANCE", true);//DB Config +} +define('UL_DEBUG', IS_DEBUG); \ No newline at end of file diff --git a/app/index.php b/app/index.php new file mode 100644 index 0000000..aa0d0e9 --- /dev/null +++ b/app/index.php @@ -0,0 +1,43 @@ +debug($_SESSION); + } else { + require_once('./lang/sec_de.php'); + } + $appDebugger->trace(); + $appLogger = AppFactory::getLogger(LOG_MODE); + // Controller erstellen + $route = new RouteFactory(); + $controller = $route->getController(@$_GET, @$_POST, $jdbcTemplate); + $controller->process(); + + echo $controller->display(); +} +?> \ No newline at end of file diff --git a/app/lang/index.html b/app/lang/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/app/lang/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lang/lang_de.ini b/app/lang/lang_de.ini new file mode 100644 index 0000000..1e3a82a --- /dev/null +++ b/app/lang/lang_de.ini @@ -0,0 +1,188 @@ +[application] +subtitle = "Eine Geschenkeliste zum kommunizieren der Geschenke und koordieren der Geschenke zwischen Angehörigen, Freunden und Bekannten." +title = "Geschenkeliste" +copyright="Copyright Lightszentip © 2014." + +[navigation] +home="Übersicht der Geschenke" +home_admin="Übersicht der Geschenke (Admin)" +changepresent = "Geschenk abwählen" +admin="Administration" +toggle="Toggle navigation" +help="Hilfe" +createpresent="Geschenk erstellen" +logout="Logout" +maintenance_settings="Wartungsmodus" +settings="Einstellungen" +signinas="Eingeloggt als " +version="Version" +createuser="Benutzer erstellen" +frontend="Frontend" +profile="Profil" +passwordforgotten="Passwort vergessen" + +[usepresent] +image="Bild" +title="Titel" +status="Status" +panel_title="Geschenk _{0}_ ausgewählt" +panel_subtitle="Sie haben das folgende Geschenk ausgewählt. Bitte notieren Sie sich den Code _{0}_, da nur mit diesem Code das Geschenk wieder freigegeben werden kann:" +description="Beschreibung" +links="Links" +modal_title="Geschenk wählen" +modal_email="Email address (optional)" +modal_emailhelp="Das Angeben der Email Adresse ist optional und schickt den Geschenkcode und die Angaben zum Geschenk an angegebene Adresse." +modal_close="Abbrechen" +modal_useit="Ich nehme das Geschenk" +modal_placeholder="Email Adresse eingeben (optional)" +share_modal_title="Geschenk teilen" +share_modal_email_to="Email Adresse des Empfängers" +share_modal_name_to="Name des Empfängers" +share_modal_email_from="Email Adresse des Absenders" +share_modal_name_from="Name des Absenders" +share_modal_share="Teilen" +share_modal_close="Abrechen" +share_modal_placeholder_email="Email Adresse eingeben" +share_modal_placeholder_optional=" (optional)" +share_modal_placeholder_name="Name" +share_modal_content="Mitteilung" +share_success_title="Das Geschenk wurde erfolgreich geteilt" +share_success_text="Das Geschenk wurde geteilt." +share_success_close="Schließen" +share_modal_emailto_info="Es können mit ; mehrere Empfänger angegeben werden" + +[presenttable] +image="Bild" +title="Titel" +status="Status" +description="Beschreibung" +links="Links zum Geschenk bei Händlern oder Herstellern" +button_useit = "Geschenk wählen" +page_size="Wähle die Anzahl Elemente auf einer Seite" +status_select="Wähle einen Status" +reset_filters="Filter zurücksetzen" +share="Teilen" +button_details="Details" + +[maintenance] +form_button_save="Eingabe speichern" +form_label_content="Subtitle" +form_label_title="Title" +form_title="Wartungsmodus (aktivieren/deaktivieren/Ändern)" +link_active="Wartungsmodus aktivieren" +link_inactive="Wartungsmodus deaktivieren" +settings_save="Änderungen wurde gespeichert" +settings_off="Der Wartungsmodus wurde deaktiviert." +settings_on="Der Wartungsmodus wurde aktiviert." + +[email] +use_present_text="Hallo,\n das Geschenk _{0}_ wurde von dir reserviert. Unter _{2}_ kannst du dir es nochmal im Detail anschauen. Freigeben kannst du es wieder unter der Url _{1}_, falls du es doch nicht schenken möchtest. Solange du es nicht freigibts kann es kein anderer auswählen." +use_present_text_html="Hallo,Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/escape.helper.php b/app/lib/escape.helper.php new file mode 100644 index 0000000..ed39640 --- /dev/null +++ b/app/lib/escape.helper.php @@ -0,0 +1,117 @@ + $value) { + $newValue[$key] = htmlentities((string) $value); + } + return $newValue; + } else { + return htmlentities((string) $variable); + } + default : + throw new Exception('Invalid escape target ' . $target); + } + } + +} + +?> \ No newline at end of file diff --git a/app/lib/i18n.class.php b/app/lib/i18n.class.php new file mode 100644 index 0000000..a05651c --- /dev/null +++ b/app/lib/i18n.class.php @@ -0,0 +1,287 @@ +filePath = $filePath; + } + + if ($cachePath != NULL) { + $this->cachePath = $cachePath; + } + + if ($fallbackLang != NULL) { + $this->fallbackLang = $fallbackLang; + } + + if ($prefix != NULL) { + $this->prefix = $prefix; + } + } + + public function init() { + if ($this->isInitialized()) { + throw new BadMethodCallException('This object from class ' . __CLASS__ . ' is already initialized. It is not possible to init one object twice!'); + } + + $this->isInitialized = true; + + $this->userLangs = $this->getUserLangs(); + + // search for language file + $this->appliedLang = NULL; + foreach ($this->userLangs as $priority => $langcode) { + $this->langFilePath = str_replace('{LANGUAGE}', $langcode, $this->filePath); + if (file_exists($this->langFilePath)) { + $this->appliedLang = $langcode; + break; + } + } + if ($this->appliedLang == NULL) { + throw new RuntimeException('No language file was found.'); + } + + // search for cache file + $this->cacheFilePath = $this->cachePath . '/php_i18n_' . md5_file(__FILE__) . '_' . $this->appliedLang . '.cache.php'; + + // if no cache file exists or if it is older than the language file create a new one + if (!file_exists($this->cacheFilePath) || filemtime($this->cacheFilePath) < filemtime($this->langFilePath)) { + switch ($this->get_file_extension()) { + case 'ini': + $config = parse_ini_file($this->langFilePath, true); + break; + case 'yml': + require_once 'vendor/spyc.php'; + $config = spyc_load_file($this->langFilePath); + break; + default: + throw new InvalidArgumentException($this->get_file_extension() . " is not a valid extension!"); + } + + $compiled = "prefix . " {\n"; + $compiled .= $this->compile($config); + $compiled .= '}'; + + file_put_contents($this->cacheFilePath, $compiled); + chmod($this->cacheFilePath, 0777); + + } + + require_once $this->cacheFilePath; + } + + public function isInitialized() { + return $this->isInitialized; + } + + public function getAppliedLang() { + return $this->appliedLang; + } + + public function getCachePath() { + return $this->cachePath; + } + + public function getFallbackLang() { + return $this->fallbackLang; + } + + public function setFilePath($filePath) { + $this->fail_after_init(); + $this->filePath = $filePath; + } + + public function setCachePath($cachePath) { + $this->fail_after_init(); + $this->cachePath = $cachePath; + } + + public function setFallbackLang($fallbackLang) { + $this->fail_after_init(); + $this->fallbackLang = $fallbackLang; + } + + public function setPrefix($prefix) { + $this->fail_after_init(); + $this->prefix = $prefix; + } + + public function setForcedLang($forcedLang) { + $this->fail_after_init(); + $this->forcedLang = $forcedLang; + } + + public function setSectionSeperator($sectionSeperator) { + $this->fail_after_init(); + $this->sectionSeperator = $sectionSeperator; + } + + /** + * getUserLangs() + * Returns the user languages + * Normally it returns an array like this: + * 1. Forced language + * 2. Language in $_GET['lang'] + * 3. Language in $_SESSION['lang'] + * 4. HTTP_ACCEPT_LANGUAGE + * 5. Fallback language + * Note: duplicate values are deleted. + * + * @return array with the user languages sorted by priority. + */ + public function getUserLangs() { + $userLangs = array(); + + // Highest priority: forced language + if ($this->forcedLang != NULL) { + $userLangs[] = $this->forcedLang; + } + + // 2nd highest priority: GET parameter 'lang' + if (isset($_GET['lang']) && is_string($_GET['lang'])) { + $userLangs[] = $_GET['lang']; + } + + // 3rd highest priority: SESSION parameter 'lang' + if (isset($_SESSION['lang']) && is_string($_SESSION['lang'])) { + $userLangs[] = $_SESSION['lang']; + } + + // 4th highest priority: HTTP_ACCEPT_LANGUAGE + if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $part) { + $userLangs[] = strtolower(substr($part, 0, 2)); + } + } + + // Lowest priority: fallback + $userLangs[] = $this->fallbackLang; + + // remove duplicate elements + $userLangs = array_unique($userLangs); + + foreach ($userLangs as $key => $value) { + $userLangs[$key] = preg_replace('/[^a-zA-Z0-9]/', '', $value); // only allow a-z, A-Z and 0-9 + } + + return $userLangs; + } + + + /** + * Recursively compile an associative array to PHP code. + */ + protected function compile($config, $prefix = '') { + $code = ''; + foreach ($config as $key => $value) { + if (is_array($value)) { + $code .= $this->compile($value, $prefix . $key . $this->sectionSeperator); + } else { + $code .= 'const ' . $prefix . $key . ' = \'' . str_replace('\'', '\\\'', $value) . "';\n"; + } + } + return $code; + } + + protected function get_file_extension() { + return substr(strrchr($this->langFilePath, '.'), 1); + } + + protected function fail_after_init() { + if ($this->isInitialized()) { + throw new BadMethodCallException('This ' . __CLASS__ . ' object is already initalized, so you can not change any settings.'); + } + } + +} diff --git a/app/lib/index.html b/app/lib/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/app/lib/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kLogger/KLogger.php b/app/lib/kLogger/KLogger.php new file mode 100644 index 0000000..ec48f75 --- /dev/null +++ b/app/lib/kLogger/KLogger.php @@ -0,0 +1,410 @@ +logInfo('Returned a million search results'); //Prints to the log file + * $log->logFatal('Oh dear.'); //Prints to the log file + * $log->logDebug('x = 5'); //Prints nothing due to current severity threshhold + * + * @author Kenny KatzgrauDirectory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/Kint.class.php b/app/lib/kint/Kint.class.php new file mode 100644 index 0000000..9541885 --- /dev/null +++ b/app/lib/kint/Kint.class.php @@ -0,0 +1,742 @@ + 0 ) { + self::$enabled = $value; + return; + } + + # ...and a getter + return self::$enabled; + } + + public static function _init() + { + # init settings + if ( isset( $GLOBALS['_kint_settings'] ) ) { + foreach ( $GLOBALS['_kint_settings'] as $key => $val ) { + self::$$key = $val; + } + } + + require KINT_DIR . 'decorators/rich.php'; + require KINT_DIR . 'decorators/concise.php'; + } + + /** + * Prints a debug backtrace + * + * @param array $trace [OPTIONAL] you can pass your own trace, otherwise, `debug_backtrace` will be called + * + * @return void + */ + public static function trace( $trace = null ) + { + if ( !Kint::enabled() ) return; + + echo Kint_Decorators_Rich::_css(); + + isset( $trace ) or $trace = debug_backtrace( true ); + + $output = array(); + foreach ( $trace as $step ) { + self::$traceCleanupCallback and $step = call_user_func( self::$traceCleanupCallback, $step ); + + # if the user defined trace cleanup function returns null, skip this line + if ( $step === null ) { + continue; + } + + if ( !isset( $step['function'] ) ) { + # invalid trace step + continue; + } + + if ( isset( $step['file'] ) AND isset( $step['line'] ) ) { + # include the source of this step + $source = self::_showSource( $step['file'], $step['line'] ); + } + + if ( isset( $step['file'] ) ) { + $file = $step['file']; + + if ( isset( $step['line'] ) ) { + $line = $step['line']; + } + } + + + $function = $step['function']; + + if ( in_array( $step['function'], self::$_statements ) ) { + if ( empty( $step['args'] ) ) { + # no arguments + $args = array(); + } else { + # sanitize the file path + $args = array( self::shortenPath( $step['args'][0] ) ); + } + } elseif ( isset( $step['args'] ) ) { + if ( empty( $step['class'] ) && !function_exists( $step['function'] ) ) { + # introspection on closures or language constructs in a stack trace is impossible before PHP 5.3 + $params = null; + } else { + try { + if ( isset( $step['class'] ) ) { + if ( method_exists( $step['class'], $step['function'] ) ) { + $reflection = new ReflectionMethod( $step['class'], $step['function'] ); + } else if ( isset( $step['type'] ) && $step['type'] == '::' ) { + $reflection = new ReflectionMethod( $step['class'], '__callStatic' ); + } else { + $reflection = new ReflectionMethod( $step['class'], '__call' ); + } + } else { + $reflection = new ReflectionFunction( $step['function'] ); + } + + # get the function parameters + $params = $reflection->getParameters(); + } catch ( Exception $e ) { + $params = null; # avoid various PHP version incompatibilities + } + } + + $args = array(); + foreach ( $step['args'] as $i => $arg ) { + if ( isset( $params[$i] ) ) { + # assign the argument by the parameter name + $args[$params[$i]->name] = $arg; + } else { + # assign the argument by number + $args[$i] = $arg; + } + } + } + + if ( isset( $step['class'] ) ) { + # Class->method() or Class::method() + $function = $step['class'] . $step['type'] . $step['function']; + } + + if ( isset( $step['object'] ) ) { + $function = $step['class'] . $step['type'] . $step['function']; + } + + $output[] = array( + 'function' => $function, + 'args' => isset( $args ) ? $args : null, + 'file' => isset( $file ) ? $file : null, + 'line' => isset( $line ) ? $line : null, + 'source' => isset( $source ) ? $source : null, + 'object' => isset( $step['object'] ) ? $step['object'] : null, + ); + + unset( $function, $args, $file, $line, $source ); + } + + require KINT_DIR . 'view/trace.phtml'; + } + + /** + * dump information about variables + * + * @param mixed $data + * + * @return void|string + */ + public static function dump( $data = null ) + { + if ( !Kint::enabled() ) return; + + # find caller information + $trace = debug_backtrace(); + list( $names, $modifier, $callee, $previousCaller ) = self::_getPassedNames( $trace ); + if ( $names === array( null ) && func_num_args() === 1 && $data === 1 ) { + $call = reset( $trace ); + if ( !isset( $call['file'] ) && isset( $call['class'] ) && $call['class'] === __CLASS__ ) { + array_shift( $trace ); + $call = reset( $trace ); + } + + while ( isset( $call['file'] ) && $call['file'] === __FILE__ ) { + array_shift( $trace ); + $call = reset( $trace ); + } + + self::trace( $trace ); + return; + } + + # process modifiers: @, + and - + switch ( $modifier ) { + case '-': + self::$_firstRun = true; + while ( ob_get_level() ) { + ob_end_clean(); + } + break; + + case '!': + self::$expandedByDefault = true; + break; + case '+': + $maxLevelsOldValue = self::$maxLevels; + self::$maxLevels = false; + break; + case '@': + $firstRunOldValue = self::$_firstRun; + self::$_firstRun = true; + break; + } + + + $data = func_num_args() === 0 + ? array( "[[no arguments passed]]" ) + : func_get_args(); + + + $output = Kint_Decorators_Rich::_css(); + $output .= Kint_Decorators_Rich::_wrapStart( $callee ); + + foreach ( $data as $k => $argument ) { + $output .= self::_dump( $argument, $names[$k] ); + } + $output .= Kint_Decorators_Rich::_wrapEnd( $callee, $previousCaller ); + + self::$_firstRun = false; + + switch ( $modifier ) { + case '+': + self::$maxLevels = $maxLevelsOldValue; + echo $output; + break; + case '@': + self::$_firstRun = $firstRunOldValue; + return $output; + break; + default: + echo $output; + break; + } + + return ''; + } + + protected static function _dump( $var, $name = '' ) + { + kintParser::reset(); + return Kint_Decorators_Rich::decorate( + kintParser::factory( $var, $name ) + ); + } + + + /** + * generic path display callback, can be configured in the settings + * + * @param string $file + * @param int $line [OPTIONAL] + * + * @return string + */ + public static function shortenPath( $file, $line = null ) + { + $file = str_replace( '\\', '/', $file ); + $shortenedName = $file; + foreach ( self::$appRootDirs as $path => $replaceString ) { + $path = str_replace( '\\', '/', $path ); + + if ( strpos( $file, $path ) === 0 ) { + $shortenedName = $replaceString . substr( $file, strlen( $path ) ); + break; + } + } + + + if ( !$line ) { # means this is called from resource type dump + return $shortenedName; + } + + if ( !self::$fileLinkFormat ) { + return "{$shortenedName} line {$line}"; + } + + $url = str_replace( array( '%f', '%l' ), array( $file, $line ), self::$fileLinkFormat ); + $class = ( strpos( $url, 'http://' ) === 0 ) ? 'class="kint-ide-link"' : ''; + + return "{$shortenedName} line {$line}"; + } + + + /** + * trace helper, shows the place in code inline + * + * @param string $file full path to file + * @param int $lineNumber the line to display + * @param int $padding surrounding lines to show besides the main one + * + * @return bool|string + */ + private static function _showSource( $file, $lineNumber, $padding = 7 ) + { + if ( !$file OR !is_readable( $file ) ) { + # continuing will cause errors + return false; + } + + # open the file and set the line position + $file = fopen( $file, 'r' ); + $line = 0; + + # Set the reading range + $range = array( + 'start' => $lineNumber - $padding, + 'end' => $lineNumber + $padding + ); + + # set the zero-padding amount for line numbers + $format = '% ' . strlen( $range['end'] ) . 'd'; + + $source = ''; + while ( ( $row = fgets( $file ) ) !== false ) { + # increment the line number + if ( ++$line > $range['end'] ) { + break; + } + + if ( $line >= $range['start'] ) { + # make the row safe for output + $row = htmlspecialchars( $row, ENT_NOQUOTES ); + + # trim whitespace and sanitize the row + $row = '' . sprintf( $format, $line ) . ' ' . $row; + + if ( $line === $lineNumber ) { + # apply highlighting to this row + $row = ''; + foreach ( $argv as $k => $v ) { + $k && print( "\n\n" ); + echo kintLite( $v ); + } + echo '' . "\n"; + } + + /** + * Alias of kintLite() + * [!!!] IMPORTANT: execution will halt after call to this function + * + * @return string + */ + function sd() + { + if ( !Kint::enabled() ) return; + + echo '
'; + foreach ( func_get_args() as $k => $v ) { + $k && print( "\n\n" ); + echo kintLite( $v ); + } + echo ''; + die; + + } + +} + + +/** + * lightweight version of Kint::dump(). Uses whitespace for formatting instead of html + * sadly not DRY yet + * + * @param $var + * @param int $level + * + * @return string + */ +function kintLite( &$var, $level = 0 ) +{ + + // initialize function names into variables for prettier string output (html and implode are also DRY) + $html = "htmlspecialchars"; + $implode = "implode"; + $strlen = "strlen"; + $count = "count"; + $getClass = "get_class"; + + + if ( $var === null ) { + return 'NULL'; + } elseif ( is_bool( $var ) ) { + return 'bool ' . ( $var ? 'TRUE' : 'FALSE' ); + } elseif ( is_float( $var ) ) { + return 'float ' . $var; + } elseif ( is_int( $var ) ) { + return 'integer ' . $var; + } elseif ( is_resource( $var ) ) { + if ( ( $type = get_resource_type( $var ) ) === 'stream' AND $meta = stream_get_meta_data( $var ) ) { + + if ( isset( $meta['uri'] ) ) { + $file = $meta['uri']; + + return "resource ({$type}) {$html( $file, 0 )}"; + } else { + return "resource ({$type})"; + } + } else { + return "resource ({$type})"; + } + } elseif ( is_string( $var ) ) { + return "string ({$strlen( $var )}) \"{$html( $var )}\""; + } elseif ( is_array( $var ) ) { + $output = array(); + $space = str_repeat( $s = ' ', $level ); + + static $marker; + + if ( $marker === null ) { + // Make a unique marker + $marker = uniqid( "\x00" ); + } + + if ( empty( $var ) ) { + return "array()"; + } elseif ( isset( $var[$marker] ) ) { + $output[] = "[\n$space$s*RECURSION*\n$space]"; + } elseif ( $level < 7 ) { + $isSeq = array_keys( $var ) === range( 0, count( $var ) - 1 ); + + $output[] = "["; + + $var[$marker] = true; + + + foreach ( $var as $key => &$val ) { + if ( $key === $marker ) continue; + + $key = $space . $s . ( $isSeq ? "" : "'{$html( $key, 0 )}' => " ); + + $dump = kintLite( $val, $level + 1 ); + $output[] = "{$key}{$dump}"; + } + + unset( $var[$marker] ); + $output[] = "$space]"; + + } else { + $output[] = "[\n$space$s*depth too great*\n$space]"; + } + return "array({$count( $var )}) {$implode( "\n", $output )}"; + } elseif ( is_object( $var ) ) { + if ( $var instanceof SplFileInfo ) { + return "object SplFileInfo " . $var->getRealPath(); + } + + // Copy the object as an array + $array = (array)$var; + + $output = array(); + $space = str_repeat( $s = ' ', $level ); + + $hash = spl_object_hash( $var ); + + // Objects that are being dumped + static $objects = array(); + + if ( empty( $array ) ) { + return "object {$getClass( $var )} {}"; + } elseif ( isset( $objects[$hash] ) ) { + $output[] = "{\n$space$s*RECURSION*\n$space}"; + } elseif ( $level < 7 ) { + $output[] = "{"; + $objects[$hash] = true; + + foreach ( $array as $key => & $val ) { + if ( $key[0] === "\x00" ) { + + $access = $key[1] === "*" ? "protected" : "private"; + + // Remove the access level from the variable name + $key = substr( $key, strrpos( $key, "\x00" ) + 1 ); + } else { + $access = "public"; + } + + $output[] = "$space$s$access $key -> " . kintLite( $val, $level + 1 ); + } + unset( $objects[$hash] ); + $output[] = "$space}"; + + } else { + $output[] = "{\n$space$s*depth too great*\n$space}"; + } + + return "object {$getClass( $var )} ({$count( $array )}) {$implode( "\n", $output )}"; + } else { + return gettype( $var ) . htmlspecialchars( var_export( $var, true ), ENT_NOQUOTES ); + } +} + +Kint::_init(); diff --git a/app/lib/kint/LICENCE b/app/lib/kint/LICENCE new file mode 100644 index 0000000..936fe1f --- /dev/null +++ b/app/lib/kint/LICENCE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Rokas Šleinius (raveren@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/app/lib/kint/composer.json b/app/lib/kint/composer.json new file mode 100644 index 0000000..cbed1f5 --- /dev/null +++ b/app/lib/kint/composer.json @@ -0,0 +1,24 @@ +{ + "name": "raveren/kint", + "description": "Kint - debugging helper for PHP developers", + "keywords": ["kint", "php", "debug"], + "type": "library", + "homepage": "https://github.com/raveren/kint", + "license": "MIT", + "authors": [ + { + "name": "Rokas Šleinius", + "homepage": "https://github.com/raveren" + }, + { + "name": "Contributors", + "homepage": "https://github.com/raveren/kint/contributors" + } + ], + "require": { + "php": ">=5.2.0" + }, + "autoload": { + "files": ["Kint.class.php"] + } +} \ No newline at end of file diff --git a/app/lib/kint/config.default.php b/app/lib/kint/config.default.php new file mode 100644 index 0000000..6be4a50 --- /dev/null +++ b/app/lib/kint/config.default.php @@ -0,0 +1,130 @@ + '<ROOT>' ) + * + * [!] EXAMPLE (for Kohana framework): + * + * $_kintSettings['appRootDirs'] = array( + * APPPATH => 'APPPATH', // make sure the constants are already defined at the time of including this config file + * SYSPATH => 'SYSPATH', + * MODPATH => 'MODPATH', + * DOCROOT => 'DOCROOT', + * ); + * + * [!] EXAMPLE #2 (for a semi-universal approach) + * + * $_kintSettings['appRootDirs'] = array( + * realpath( __DIR__ . '/../../..' ) => 'ROOT', // go up as many levels as needed in the realpath() param + * ); + * + * $_kintSettings['fileLinkFormat'] = 'http://localhost:8091/?message=%f:%l'; + * + */ +$_kintSettings['appRootDirs'] = array( + $_SERVER['DOCUMENT_ROOT'] => '../../../;' +); + + +/** + * @var callable|null + * + * @param array $step each step of the backtrace is passed to this callback to clean it up or skip it entirely + * + * @return array|null you can return null if you want to bypass outputting this step + * + * [!] EXAMPLE: + * + * $_kintSettings['traceCleanupCallback'] = function( $traceStep ) { + * if ( isset( $traceStep['class'] ) && strtolower( $traceStep['class'] ) === 'errorHandler' ) { + * return null; + * } + * + * if ( isset( $traceStep['function'] ) && strtolower( $traceStep['function'] ) === '__tostring' ) { + * $traceStep['function'] = "[object converted to string]"; + * } + * + * return $traceStep; + * }; + */ +$_kintSettings['traceCleanupCallback'] = null; + + +/** @var int max length of string before it is truncated and displayed separately in full. Zero or false to disable */ +$_kintSettings['maxStrLength'] = 60; + +/** @var array possible alternative char encodings in order of probability, eg. array('windows-1251') */ +$_kintSettings['charEncodings'] = array(); + + +/** @var int max array/object levels to go deep, if zero no limits are applied */ +$_kintSettings['maxLevels'] = 5; + + +/** @var bool whether dumped indexed arrays that are in ideal sequence are displayed */ +$_kintSettings['hideSequentialKeys'] = true; + + +/** @var string name of theme for rich view */ +$_kintSettings['theme'] = 'original'; + + +/** + * @var callback filters array/object keys before outputting; return false if you do not wish to see it in the output + * + * @param string $key the key being output + * @param mixed $val the contents of the dumped element in case you need it + * + * @return bool return false to skip displaying + * + * [!] EXAMPLE: + * + * $_kintSettings['keyFilterCallback'] = function( $key, $val ) { + * if ( preg_match( '#_mt$#', $key ) ) { + * return false; + * } + * + * if ( $val === '--testing--' ) { + * return false; + * } + * + * // no need to return true to continue output + * }; + * + */ +$_kintSettings['keyFilterCallback'] = null; + + +/** @var bool only set to true if you want to develop kint and know what you're doing */ +$_kintSettings['devel'] = false; + + +unset( $_kintSettings ); \ No newline at end of file diff --git a/app/lib/kint/decorators/concise.php b/app/lib/kint/decorators/concise.php new file mode 100644 index 0000000..4385845 --- /dev/null +++ b/app/lib/kint/decorators/concise.php @@ -0,0 +1,58 @@ +extendedValue + * + * @param kintVariableData $kintVar + * + * @return string + */ + public static function decorate( kintVariableData $kintVar ) + { + if ( $kintVar->extendedValue !== null || !empty( $kintVar->alternatives ) ) { + return Kint_Decorators_Rich::decorate( $kintVar ); + } + + if ( $kintVar->value !== null ) { + $output = 'name !== null ) { + $output .= $kintVar->name . " "; + } + + if ( $kintVar->type !== null ) { + $output .= $kintVar->type; + if ( $kintVar->subtype !== null ) { + $output .= " " . $kintVar->subtype; + } + $output .= " "; + } + + if ( $kintVar->operator !== null ) { + $output .= $kintVar->operator . ""; + } + + if ( $kintVar->size !== null ) { + $output .= "(" . $kintVar->size . ") "; + } + + $output = trim( $output ) . '">' . $kintVar->value . ''; + } else { + $output = 'NULL'; + } + + return $output; + } +} \ No newline at end of file diff --git a/app/lib/kint/decorators/plain.php b/app/lib/kint/decorators/plain.php new file mode 100644 index 0000000..203e60c --- /dev/null +++ b/app/lib/kint/decorators/plain.php @@ -0,0 +1,54 @@ +'; + + $extendedPresent = $kintVar->extendedValue !== null || $kintVar->alternatives !== null; + + if ( $extendedPresent ) { + $class = 'kint-parent'; + if ( Kint::$expandedByDefault ) { + $class .= ' kint-show'; + } + $output .= '
' . $kintVar->extendedValue . ''; + } else { + $output .= self::decorate( $kintVar->extendedValue ); //it's kint's container + } + + } elseif ( isset( $kintVar->alternatives ) ) { + $output .= "
' . $var . ''; + } elseif ( isset( $var ) ) { + throw new Exception( + 'Kint has encountered an error, ' + . 'please paste this report to https://github.com/raveren/kint/issues
Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/arrayobject.php b/app/lib/kint/parsers/custom/arrayobject.php new file mode 100644 index 0000000..4c15e29 --- /dev/null +++ b/app/lib/kint/parsers/custom/arrayobject.php @@ -0,0 +1,26 @@ +getParentClass(); + + if ( $parentClass !== false && $parentClass->name === 'ArrayObject' ) { + $arrayCopy = $variable->getArrayCopy(); + foreach ( $arrayCopy as $k => $var ) { + $t = kintParser::factory( $var ); + $t->name = "'{$k}'"; + $t->operator = '=>'; + $this->value[] = $t; + } + + $this->type = 'ArrayObject contents'; + $this->size = count( $arrayCopy ); + } else { + return false; + } + } +} diff --git a/app/lib/kint/parsers/custom/classmethods.php b/app/lib/kint/parsers/custom/classmethods.php new file mode 100644 index 0000000..58c7f4c --- /dev/null +++ b/app/lib/kint/parsers/custom/classmethods.php @@ -0,0 +1,151 @@ +getMethods() as $method) { + $params = array(); + + // Access type + $access = implode(' ', \Reflection::getModifierNames($method->getModifiers())); + + // Method parameters + foreach($method->getParameters() as $param) { + $paramString = ''; + + if ( $param->isArray() ) { + $paramString .= 'array '; + } else { + try { + if (( $paramClassName = $param->getClass() )) { + $paramString .= $paramClassName->name . ' '; + } + } catch ( ReflectionException $e ) { + preg_match( '/\[\s\<\w+?>\s([\w]+)/s', $param->__toString(), $matches ); + $paramClassName = isset( $matches[1] ) ? $matches[1] : ''; + + $paramString .= ' UNDEFINED CLASS (' . $paramClassName . ') '; + } + } + + $paramString .= ($param->isPassedByReference() ? '&' : '') . '$' . $param->getName(); + + if($param->isDefaultValueAvailable()) { + if(is_array($param->getDefaultValue())) { + $arrayValues = array(); + foreach($param->getDefaultValue() as $key => $value) { + $arrayValues[] = $key . ' => ' . $value; + } + + $defaultValue = 'array(' . implode(', ', $arrayValues) . ')'; + } elseif($param->getDefaultValue() === null){ + $defaultValue = 'NULL'; + } elseif($param->getDefaultValue() === false){ + $defaultValue = 'false'; + } elseif($param->getDefaultValue() === true){ + $defaultValue = 'true'; + } elseif($param->getDefaultValue() === ''){ + $defaultValue = '""'; + } else { + $defaultValue = $param->getDefaultValue(); + } + + $paramString .= ' = ' . $defaultValue; + } + + $params[] = $paramString; + } + + $output = new \kintVariableData(); + + // Simple DocBlock parser, look for @return + if(($docBlock = $method->getDocComment())) { + $matches = array(); + if(preg_match_all('/@(\w+)\s+(.*)\r?\n/m', $docBlock, $matches)) { + $lines = array_combine($matches[1], $matches[2]); + if(isset($lines['return'])) { + $output->operator = '->'; + # since we're outputting code, assumption that the string is utf8 is most likely correct + # and saves resources + $output->type = self::_escape( $lines['return'], 'UTF-8' ); + } + } + } + + $output->name = ($method->returnsReference() ? '&' : '') . $method->getName() . '(' + . implode(', ', $params) . ')'; + $output->access = $access; + + if(is_string($docBlock)) { + $lines = array(); + foreach(explode("\n", $docBlock) as $line) { + $line = trim($line); + + if(in_array($line, array('/**', '/*', '*/'))) { + continue; + }elseif(strpos($line, '*') === 0) { + $line = substr($line, 1); + } + + $lines[] = self::_escape( trim( $line ), 'UTF-8' ); + } + + $output->extendedValue = implode("\n", $lines) . "\n\n"; + } + + $declaringClass = $method->getDeclaringClass(); + $declaringClassName = $declaringClass->getName(); + + if($declaringClassName !== $className) { + $output->extendedValue .= "Inherited from {$declaringClassName}\n"; + } + + $fileName = \Kint::shortenPath($method->getFileName(), $method->getStartLine()); + + if($fileName) { + $output->extendedValue .= "Defined in {$fileName}"; + } + + $sortName = $access . $method->getName(); + + if($method->isPrivate()) { + $private[$sortName] = $output; + } elseif($method->isProtected()) { + $protected[$sortName] = $output; + } else { + $public[$sortName] = $output; + } + } + + if(!$private && !$protected && !$public) { + self::$cache[$className] = false; + } + + ksort($public); + ksort($protected); + ksort($private); + + self::$cache[$className] = $public + $protected + $private; + } + + $this->value = self::$cache[$className]; + $this->type = 'Available methods'; + $this->size = count(self::$cache[$className]); + } +} \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/classstatics.php b/app/lib/kint/parsers/custom/classstatics.php new file mode 100644 index 0000000..1c6d0e4 --- /dev/null +++ b/app/lib/kint/parsers/custom/classstatics.php @@ -0,0 +1,54 @@ +getProperties( ReflectionProperty::IS_STATIC ) as $property ) { + if ( $property->isPrivate() ) { + if ( !method_exists( $property, 'setAccessible' ) ) { + break; + } + $property->setAccessible( true ); + $access = "private"; + } elseif ( $property->isProtected() ) { + $property->setAccessible( true ); + $access = "protected"; + } else { + $access = 'public'; + } + + if ( Kint::$keyFilterCallback + && call_user_func( Kint::$keyFilterCallback, $property->getName(), $property->getValue() ) === false + ) { + continue; + } + + $_ = $property->getValue(); + $output = kintParser::factory( $_, '$' . $property->getName() ); + + $output->access = $access; + $output->operator = '::'; + $extendedValue[] = $output; + } + + foreach ( $reflection->getConstants() as $constant => $val ) { + $output = kintParser::factory( $val, $constant ); + + $output->access = 'constant'; + $output->operator = '::'; + $extendedValue[] = $output; + } + + if ( empty( $extendedValue ) ) return false; + + $this->value = $extendedValue; + $this->type = 'Static class properties'; + $this->size = count( $extendedValue ); + } +} \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/color.php b/app/lib/kint/parsers/custom/color.php new file mode 100644 index 0000000..21d1f39 --- /dev/null +++ b/app/lib/kint/parsers/custom/color.php @@ -0,0 +1,400 @@ +'#f0f8ff','antiquewhite'=>'#faebd7','aqua'=>'#00ffff','aquamarine'=>'#7fffd4','azure'=>'#f0ffff', + 'beige'=>'#f5f5dc','bisque'=>'#ffe4c4','black'=>'#000000','blanchedalmond'=>'#ffebcd','blue'=>'#0000ff', + 'blueviolet'=>'#8a2be2','brown'=>'#a52a2a','burlywood'=>'#deb887','cadetblue'=>'#5f9ea0','chartreuse'=>'#7fff00', + 'chocolate'=>'#d2691e','coral'=>'#ff7f50','cornflowerblue'=>'#6495ed','cornsilk'=>'#fff8dc','crimson'=>'#dc143c', + 'cyan'=>'#00ffff','darkblue'=>'#00008b','darkcyan'=>'#008b8b','darkgoldenrod'=>'#b8860b','darkgray'=>'#a9a9a9', + 'darkgrey'=>'#a9a9a9','darkgreen'=>'#006400','darkkhaki'=>'#bdb76b','darkmagenta'=>'#8b008b', + 'darkolivegreen'=>'#556b2f','darkorange'=>'#ff8c00','darkorchid'=>'#9932cc','darkred'=>'#8b0000', + 'darksalmon'=>'#e9967a','darkseagreen'=>'#8fbc8f','darkslateblue'=>'#483d8b','darkslategray'=>'#2f4f4f', + 'darkslategrey'=>'#2f4f4f','darkturquoise'=>'#00ced1','darkviolet'=>'#9400d3','deeppink'=>'#ff1493', + 'deepskyblue'=>'#00bfff','dimgray'=>'#696969','dimgrey'=>'#696969','dodgerblue'=>'#1e90ff', + 'firebrick'=>'#b22222','floralwhite'=>'#fffaf0','forestgreen'=>'#228b22','fuchsia'=>'#ff00ff', + 'gainsboro'=>'#dcdcdc','ghostwhite'=>'#f8f8ff','gold'=>'#ffd700','goldenrod'=>'#daa520','gray'=>'#808080', + 'grey'=>'#808080','green'=>'#008000','greenyellow'=>'#adff2f','honeydew'=>'#f0fff0','hotpink'=>'#ff69b4', + 'indianred'=>'#cd5c5c','indigo'=>'#4b0082','ivory'=>'#fffff0','khaki'=>'#f0e68c','lavender'=>'#e6e6fa', + 'lavenderblush'=>'#fff0f5','lawngreen'=>'#7cfc00','lemonchiffon'=>'#fffacd','lightblue'=>'#add8e6', + 'lightcoral'=>'#f08080','lightcyan'=>'#e0ffff','lightgoldenrodyellow'=>'#fafad2','lightgray'=>'#d3d3d3', + 'lightgrey'=>'#d3d3d3','lightgreen'=>'#90ee90','lightpink'=>'#ffb6c1','lightsalmon'=>'#ffa07a', + 'lightseagreen'=>'#20b2aa','lightskyblue'=>'#87cefa','lightslategray'=>'#778899','lightslategrey'=>'#778899', + 'lightsteelblue'=>'#b0c4de','lightyellow'=>'#ffffe0','lime'=>'#00ff00','limegreen'=>'#32cd32','linen'=>'#faf0e6', + 'magenta'=>'#ff00ff','maroon'=>'#800000','mediumaquamarine'=>'#66cdaa','mediumblue'=>'#0000cd', + 'mediumorchid'=>'#ba55d3','mediumpurple'=>'#9370d8','mediumseagreen'=>'#3cb371','mediumslateblue'=>'#7b68ee', + 'mediumspringgreen'=>'#00fa9a','mediumturquoise'=>'#48d1cc','mediumvioletred'=>'#c71585', + 'midnightblue'=>'#191970','mintcream'=>'#f5fffa','mistyrose'=>'#ffe4e1','moccasin'=>'#ffe4b5', + 'navajowhite'=>'#ffdead','navy'=>'#000080','oldlace'=>'#fdf5e6','olive'=>'#808000','olivedrab'=>'#6b8e23', + 'orange'=>'#ffa500','orangered'=>'#ff4500','orchid'=>'#da70d6','palegoldenrod'=>'#eee8aa','palegreen'=>'#98fb98', + 'paleturquoise'=>'#afeeee','palevioletred'=>'#d87093','papayawhip'=>'#ffefd5','peachpuff'=>'#ffdab9', + 'peru'=>'#cd853f','pink'=>'#ffc0cb','plum'=>'#dda0dd','powderblue'=>'#b0e0e6','purple'=>'#800080', + 'red'=>'#ff0000','rosybrown'=>'#bc8f8f','royalblue'=>'#4169e1','saddlebrown'=>'#8b4513','salmon'=>'#fa8072', + 'sandybrown'=>'#f4a460','seagreen'=>'#2e8b57','seashell'=>'#fff5ee','sienna'=>'#a0522d','silver'=>'#c0c0c0', + 'skyblue'=>'#87ceeb','slateblue'=>'#6a5acd','slategray'=>'#708090','slategrey'=>'#708090','snow'=>'#fffafa', + 'springgreen'=>'#00ff7f','steelblue'=>'#4682b4','tan'=>'#d2b48c','teal'=>'#008080','thistle'=>'#d8bfd8', + 'tomato'=>'#ff6347','turquoise'=>'#40e0d0','violet'=>'#ee82ee','wheat'=>'#f5deb3','white'=>'#ffffff', + 'whitesmoke'=>'#f5f5f5','yellow'=>'#ffff00','yellowgreen'=>'#9acd32' + ); + + + protected function _parse( & $variable ) + { + if ( !self::_fits( $variable ) ) return false; + + $this->type = 'CSS color'; + $variants = self::_convert( $variable ); + $this->value = + "Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/json.php b/app/lib/kint/parsers/custom/json.php new file mode 100644 index 0000000..0327468 --- /dev/null +++ b/app/lib/kint/parsers/custom/json.php @@ -0,0 +1,17 @@ +value = kintParser::factory( $val )->extendedValue; + $this->type = 'JSON'; + } +} \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/microtime.php b/app/lib/kint/parsers/custom/microtime.php new file mode 100644 index 0000000..a51a051 --- /dev/null +++ b/app/lib/kint/parsers/custom/microtime.php @@ -0,0 +1,54 @@ +value = @date( 'Y-m-d H:i:s', $sec ) . '.' . substr( $usec, 2, 4 ); + + $numberOfCalls = count( self::$_times ); + if ( $numberOfCalls > 0 ) { # meh, faster than count($times) > 1 + $lap = $time - end( self::$_times ); + self::$_laps[] = $lap; + + $this->value .= "\nSINCE LAST CALL: " . round( $lap, 4 ) . 's.'; + if ( $numberOfCalls > 1 ) { + $this->value .= "\nSINCE START: " . round( $time - self::$_times[0], 4 ) . 's.'; + $this->value .= "\nAVERAGE DURATION: " + . round( array_sum( self::$_laps ) / $numberOfCalls, 4 ) . 's.'; + } + } + + $unit = array( 'B', 'KB', 'MB', 'GB', 'TB' ); + $this->value .= "\nMEMORY USAGE: " . $size . " bytes (" + . round( $size / pow( 1024, ( $i = floor( log( $size, 1024 ) ) ) ), 3 ) . ' ' . $unit[$i] . ")"; + + self::$_times[] = $time; + $this->type = 'Stats'; + } + + /* + function test() { + $x = ''; + d( microtime() ); + for ( $i = 0; $i < 10; $i++ ) { + $x .= str_repeat( 'x', mt_rand( 128 * 1024, 5 * 1024 * 1024 ) ); + usleep( mt_rand( 0, 1000 * 1000 ) ); + d( microtime() ); + } + unset( $x ); + dd( microtime() ); + } + */ +} \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/splfileinfo.php b/app/lib/kint/parsers/custom/splfileinfo.php new file mode 100644 index 0000000..6b14f67 --- /dev/null +++ b/app/lib/kint/parsers/custom/splfileinfo.php @@ -0,0 +1,12 @@ +type = 'object'; + $this->subtype = 'SplFileInfo'; + $this->value = Kint::shortenPath( $variable->getRealPath() ); + } +} \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/splobjectstorage.php b/app/lib/kint/parsers/custom/splobjectstorage.php new file mode 100644 index 0000000..c355771 --- /dev/null +++ b/app/lib/kint/parsers/custom/splobjectstorage.php @@ -0,0 +1,20 @@ +rewind(); + while ( $variable->valid() ) { + $current = $variable->current(); + $this->value[] = kintParser::factory( $current ); + $variable->next(); + } + + $this->type = 'Storage contents'; + $this->size = $variable->count(); + } +} \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/timestamp.php b/app/lib/kint/parsers/custom/timestamp.php new file mode 100644 index 0000000..4c5f487 --- /dev/null +++ b/app/lib/kint/parsers/custom/timestamp.php @@ -0,0 +1,22 @@ +type = 'timestamp'; + # avoid dreaded "Timezone must be set" error + $this->value = @date( 'Y-m-d H:i:s', $variable ); + } +} \ No newline at end of file diff --git a/app/lib/kint/parsers/custom/xml.php b/app/lib/kint/parsers/custom/xml.php new file mode 100644 index 0000000..50d0def --- /dev/null +++ b/app/lib/kint/parsers/custom/xml.php @@ -0,0 +1,18 @@ +value = kintParser::factory( $xml )->extendedValue; + $this->type = 'XML'; + } +} \ No newline at end of file diff --git a/app/lib/kint/parsers/index.html b/app/lib/kint/parsers/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/app/lib/kint/parsers/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/parsers/parser.class.php b/app/lib/kint/parsers/parser.class.php new file mode 100644 index 0000000..6dd4ef6 --- /dev/null +++ b/app/lib/kint/parsers/parser.class.php @@ -0,0 +1,571 @@ + self::$_level, + 'objects' => self::$_objects, + ); + + self::$_level++; + + $name = self::_escape( $name ); + $varData = new kintVariableData; + $varData->name = $name; + + # first parse the variable based on its type + $varType = gettype( $variable ); + $varType === 'unknown type' and $varType = 'unknown'; # PHP 5.4 inconsistency + $methodName = '_parse_' . $varType; + + # base type parser returning false means "stop processing further": e.g. recursion + if ( self::$methodName( $variable, $varData ) === false ) { + self::$_level--; + return $varData; + } + + if ( !self::$_skipAlternatives) { + # if an alternative returns something that can be represented in an alternative way, don't :) + self::$_skipAlternatives = true; + + # now check whether the variable can be represented in a different way + foreach ( self::$_customDataTypes as $parserClass ) { + $className = 'Kint_Parsers_' . $parserClass; + + /** @var $object kintParser */ + $object = new $className; + $object->name = $name; # the parser may overwrite the name value, so set it first + + if ( $object->_parse( $variable ) !== false ) { + $varData->alternatives[] = $object; + } + } + + + # combine extended values with alternative representations if applicable + if ( !empty( $varData->alternatives ) && isset( $varData->extendedValue ) ) { + $a = new kintVariableData; + + $a->value = $varData->extendedValue; + $a->type = $varData->type; + $a->size = $varData->size; + + array_unshift( $varData->alternatives, $a ); + $varData->extendedValue = null; + } + + self::$_skipAlternatives = false; + } + + self::$_level = $revert['level']; + self::$_objects = $revert['objects']; + return $varData; + } + + private static function _checkDepth() + { + return Kint::$maxLevels != 0 && self::$_level > Kint::$maxLevels; + } + + private static function _isArrayTabular( $variable ) + { + foreach ( $variable as $row ) { + if ( is_array( $row ) && !empty( $row ) ) { + if ( isset( $keys ) ) { + if ( $keys === array_keys( $row ) ) { // two rows have same keys in a row? Close enough. + return true; + } + } else { + + foreach ( $row as $col ) { + if ( !is_scalar( $col ) && $col !== null ) { + break 2; + } + } + + $keys = array_keys( $row ); + } + } else { + break; + } + } + + return false; + } + + private static $_dealingWithGlobals = false; + + private static function _parse_array( &$variable, kintVariableData $variableData ) + { + isset( self::$_marker ) or self::$_marker = "\x00" . uniqid(); + + # naturally, $GLOBALS variable is an intertwined recursion nightmare, use black magic + $globalsDetector = false; + if ( array_key_exists( 'GLOBALS', $variable ) && is_array( $variable['GLOBALS'] ) ) { + $globalsDetector = "\x01" . uniqid(); + + $variable['GLOBALS'][$globalsDetector] = true; + if ( isset( $variable[$globalsDetector] ) ) { + unset( $variable[$globalsDetector] ); + self::$_dealingWithGlobals = true; + } else { + unset( $variable['GLOBALS'][$globalsDetector] ); + $globalsDetector = false; + } + } + + $variableData->type = 'array'; + $variableData->size = count( $variable ); + + if ( $variableData->size === 0 ) { + return; + } + if ( isset( $variable[self::$_marker] ) ) { # recursion; todo mayhaps show from where + if ( self::$_dealingWithGlobals ) { + $variableData->value = '*RECURSION*'; + } else { + unset( $variable[self::$_marker] ); + $variableData->value = self::$_marker; + } + return false; + } + if ( self::_checkDepth() ) { + $variableData->extendedValue = "*DEPTH TOO GREAT*"; + return false; + } + + $isSequential = self::_isSequential( $variable ); + + $tabular = self::_isArrayTabular( $variable ); + if ( $tabular ) { + + $firstRow = true; + $extendedValue = '' . ( $isSequential ? '#' . ( $rowIndex + 1 ) : $rowIndex ) . ' | '; + if ( $firstRow ) { + $extendedValue .= ''; + } + + foreach ( $arrayKeys as $key ) { + if ( $firstRow ) { + $extendedValue .= ' | ' . htmlspecialchars( $key ) . ' | '; + } + + if ( !array_key_exists( $key, $row ) ) { + $output .= ''; + continue; + } + + # display strings in their full length so as not to trigger rich decoration + $maxStrLength = kint::$maxStrLength; + kint::$maxStrLength = false; + $var = kintParser::factory( $row[$key] ); + kint::$maxStrLength = $maxStrLength; + + if ( $var->value === self::$_marker ) { + $variableData->value = '*RECURSION*'; + return false; + } elseif ( $var->value === '*RECURSION*' ) { + $output .= ' | ' . Kint_Decorators_Concise::decorate( $var ) . ' | '; + } else { + $output .= '' . Kint_Decorators_Concise::decorate( $var ) . ' | '; + } + unset( $var ); + } + + if ( $firstRow ) { + $extendedValue .= '
---|---|---|---|---|---|
Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/scripts/source.reg b/app/lib/kint/scripts/source.reg new file mode 100644 index 0000000..3d80930 --- /dev/null +++ b/app/lib/kint/scripts/source.reg @@ -0,0 +1,12 @@ +REGEDIT4 + +[HKEY_CLASSES_ROOT\source] +@="URL:source Protocol" +"URL Protocol"="" + +[HKEY_CLASSES_ROOT\source\shell] + +[HKEY_CLASSES_ROOT\source\shell\open] + +[HKEY_CLASSES_ROOT\source\shell\open\command] +@="wscript.exe \"C:\\Program Files\\bin\\source.vbs\" \"%1\"" \ No newline at end of file diff --git a/app/lib/kint/scripts/source.vbs b/app/lib/kint/scripts/source.vbs new file mode 100644 index 0000000..3345dbe --- /dev/null +++ b/app/lib/kint/scripts/source.vbs @@ -0,0 +1,80 @@ +'INSTALLATION: +'set editor link format to 'source:Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/view/js/_kint.js b/app/lib/kint/view/js/_kint.js new file mode 100644 index 0000000..b272062 --- /dev/null +++ b/app/lib/kint/view/js/_kint.js @@ -0,0 +1,344 @@ +/** +java -jar compiler.jar --js $FileName$ --js_output_file ../inc/kint.js --compilation_level ADVANCED_OPTIMIZATIONS --output_wrapper "(function(){%output%})()" +*/ + +if ( typeof kintInitialized === 'undefined' ) { + kintInitialized = 1; + var kint = { + visiblePluses : [], // all visible toggle carets + currentPlus : -1, // currently selected caret + + selectText : function( element ) { + var selection = window.getSelection(), + range = document.createRange(); + + range.selectNodeContents(element); + selection.removeAllRanges(); + selection.addRange(range); + }, + + hasClass : function( target, className ) { + if ( typeof className === 'undefined' ) { + className = 'kint-show'; + } + + return new RegExp('(\\s|^)' + className + '(\\s|$)').test(target.className); + }, + + addClass : function( ele, className ) { + if ( typeof className === 'undefined' ) { + className = 'kint-show'; + } + + kint.removeClass(ele, className).className += (" " + className); + }, + + removeClass : function( ele, className ) { + if ( typeof className === 'undefined' ) { + className = 'kint-show'; + } + + ele.className = ele.className.replace( + new RegExp('(\\s|^)' + className + '(\\s|$)'), ' ' + ); + return ele; + }, + + next : function( element ) { + do { + element = element.nextElementSibling; + } while ( element.nodeName.toLowerCase() !== 'dd' ); + + return element; + }, + + toggle : function( element, hide ) { + var parent = kint.next(element); + + if ( typeof hide === 'undefined' ) { + hide = kint.hasClass(element); + } + + if ( hide ) { + kint.removeClass(element); + } else { + kint.addClass(element); + } + + if ( parent.childNodes.length === 1 ) { + parent = parent.childNodes[0].childNodes[0]; // reuse variable cause I can + + if ( kint.hasClass(parent, 'kint-parent') ) { + kint.toggle(parent, hide) + } + } + }, + + toggleChildren : function( element, hide ) { + var parent = kint.next(element) + , nodes = parent.getElementsByClassName('kint-parent') + , i = nodes.length; + + if ( typeof hide === 'undefined' ) { + hide = kint.hasClass(element); + } + + while ( i-- ) { + kint.toggle(nodes[i], hide); + } + kint.toggle(element, hide); + }, + + toggleAll : function( caret ) { + var elements = document.getElementsByClassName('kint-parent'), + i = elements.length, + visible = kint.hasClass(caret.parentNode); + + while ( i-- ) { + kint.toggle(elements[i], visible); + } + }, + + switchTab : function( target ) { + var lis, el = target, index = 0; + + target.parentNode.getElementsByClassName('kint-active-tab')[0].className = ''; + target.className = 'kint-active-tab'; + + // take the index of clicked title tab and make the same n-th content tab visible + while ( el = el.previousSibling ) el.nodeType === 1 && index++; + lis = target.parentNode.nextSibling.childNodes; + for ( var i = 0; i < lis.length; i++ ) { + if ( i === index ) { + lis[i].style.display = 'block'; + + if ( lis[i].childNodes.length === 1 ) { + el = lis[i].childNodes[0].childNodes[0]; + + if ( kint.hasClass(el, 'kint-parent') ) { + kint.toggle(el, false) + } + } + } else { + lis[i].style.display = 'none'; + } + } + }, + + isSibling : function( el ) { + for ( ; ; ) { + el = el.parentNode; + if ( !el || kint.hasClass(el, 'kint') ) { + break; + } + } + + return !!el; + }, + + fetchVisiblePluses : function() { + kint.visiblePluses = []; + Array.prototype.slice.call(document.querySelectorAll('.kint nav, .kint-tabs>li:not(.kint-active-tab)'), 0) + .forEach( + function( el ) { + if ( el.offsetWidth !== 0 || el.offsetHeight !== 0 ) { + kint.visiblePluses.push(el) + } + } + ); + }, + + keyCallBacks : { + cleanup : function( i ) { + var focusedClass = 'kint-focused'; + var prevElement = document.querySelector('.' + focusedClass); + prevElement && kint.removeClass(prevElement, focusedClass); + + if ( i !== -1 ) { + var el = kint.visiblePluses[i]; + kint.addClass(el, focusedClass); + + + var offsetTop = function( el ) { + return el.offsetTop + ( el.offsetParent ? offsetTop(el.offsetParent) : 0 ); + }; + + var top = offsetTop(el) - (window.innerHeight / 2 ); + window.scrollTo(0, top); + } + + kint.currentPlus = i; + }, + + moveCursor : function( up, i ) { + // todo make the first VISIBLE plus active + if ( up ) { + if ( --i < 0 ) { + i = kint.visiblePluses.length - 1; + } + } else { + if ( ++i >= kint.visiblePluses.length ) { + i = 0; + } + } + + kint.keyCallBacks.cleanup(i); + return false; + } + } + }; + + window.addEventListener("click", function( e ) { + var target = e.target + , nodeName = target.nodeName.toLowerCase(); + + if ( !kint.isSibling(target) ) return; + + // auto-select name of variable + if ( nodeName === 'dfn' ) { + kint.selectText(target); + target = target.parentNode; + } else if ( nodeName === 'var' ) { // stupid workaround for misc elements + target = target.parentNode; // to not stop event from further propagating + nodeName = target.nodeName.toLowerCase() + } + + // switch tabs + if ( nodeName === 'li' && target.parentNode.className === 'kint-tabs' ) { + if ( target.className !== 'kint-active-tab' ) { + kint.switchTab(target); + if ( kint.currentPlus !== -1 ) kint.fetchVisiblePluses(); + } + return false; + } + + // handle clicks on the navigation caret + if ( nodeName === 'nav' ) { + // ensure doubleclick has different behaviour, see below + setTimeout(function() { + var timer = parseInt(target.kintTimer, 10); + if ( timer > 0 ) { + target.kintTimer--; + } else { + kint.toggleChildren(target.parentNode); //Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/view/less/_kint.less b/app/lib/kint/view/less/_kint.less new file mode 100644 index 0000000..7fed5d0 --- /dev/null +++ b/app/lib/kint/view/less/_kint.less @@ -0,0 +1,340 @@ +@border: 1px solid @border-color; + +.selection() { + background : @border-color-hover; + color : @text-color; +} + +// +// BASE STYLES +// -------------------------------------------------- + +.kint::selection { .selection() } + +.kint::-moz-selection { .selection() } + +.kint::-webkit-selection { .selection() } + +.kint { + font-family : @default-font; + color : @text-color; + padding : 0; + margin : 10px 0; + font-size : 10pt; + line-height : 15px; + white-space : nowrap; + overflow-x : auto; + text-align : left; + + * { + float : none !important; + padding : 0; + margin : 0; + } + + dt { + background : @main-background; + border : @border; + color : @text-color; + display : block; + font-weight : bold; + list-style : none outside none; + padding : @spacing * 1px; + + &:hover { + border-color : @border-color-hover; + } + } + + > dl dl { + padding : 0 0 0 15px; + border-left : 1px dashed @border-color; + } + +// +// DROPDOWN CARET +// -------------------------------------------------- + + nav { + display : inline-block; + height : 15px; + width : 15px; + margin-right : 3px; + vertical-align : middle; + content : ' '; + cursor : pointer; + background : @caret-image no-repeat scroll 0 0 transparent; + } + + dt.kint-parent:hover nav { + background-position : 0 -15px; + } + + dt.kint-parent.kint-show:hover > nav { + background-position : 0 -45px; + } + + dt.kint-show > nav { + background-position : 0 -30px; + } + + dt.kint-parent + dd { + display : none; + } + + dt.kint-parent.kint-show + dd { + display : block; + } + +// +// INDIVIDUAL ITEMS +// -------------------------------------------------- + + var { + color : @variable-type-color; + font-style : normal; + } + + dt:hover var { + color : @variable-type-color-hover; + } + + dfn { + font-style : normal; + font-family : monospace; + color : @variable-name-color; + } + + pre { + color : @text-color; + margin : 0 0 0 15px; + padding : 5px; + overflow-y : hidden; + border-top : 0; + border : @border; + background : @main-background; + display : block; + } + + footer { + padding : 0 3px 3px; + font-size : .7em + } + + a { + color : @text-color; + text-shadow : none; + + &:hover { + color : @variable-name-color; + border-bottom : 1px dotted @variable-name-color; + } + } + +// +// TABS +// -------------------------------------------------- + + ul { + list-style : none; + padding-left : @spacing * 3px; + } + + ul.kint-tabs { + margin : 0 0 0 @spacing * 3px; + padding-left : 0; + background : @main-background; + border : @border; + border-top : 0; + + li { + background : @secondary-background; + cursor : pointer; + display : inline-block; + height : 16px + ceil(8px * (@spacing / 5)); + line-height : 16px + ceil(8px * (@spacing / 5)); + margin : 0 @spacing * 1px @spacing * 1px; + padding : 0 2px + @spacing * 2px floor(3px * (@spacing / 5)); + border : @border; + + &:hover { + border : 1px solid @border-color-hover; + } + + &:hover var { + color : @variable-type-color-hover; + } + + &.kint-active-tab { + background : @main-background; + border : @border; + border-top : 0; + font-weight : bold; + margin-top : -1px; + padding-bottom : floor(3px * (@spacing / 5)); + padding-top : 1px + ceil(3px * (@spacing / 5)); + border-right : @border; + } + } + + li+li { + margin-left : 0 + } + } + + dt:hover + dd > ul > li.kint-active-tab { + border-color : @border-color-hover; + } + + dt:hover + dd > ul > li.kint-active-tab var { + color : @variable-type-color-hover; + } + + ul:not(.kint-tabs)>li:not(:first-child) { + display : none; + } +} + +// +// REPORT +// -------------------------------------------------- + +.kint-report { + border-collapse : collapse; + empty-cells : show; + border-spacing : 0; + + * { + text-align : left; + padding : 0; + margin : 0; + font-size : 9pt; + overflow : hidden; + font-family : @default-font; + color : @text-color; + } + + dt { + padding : 0; + border : 0; + background: none; + } + + dt.kint-parent { + max-width : 180px; + min-width : 100%; + overflow : hidden; + text-overflow : ellipsis; + white-space : nowrap; + } + + dt.kint-parent.kint-show { + border-bottom: @border; + } + + td, + th { + border : @border; + vertical-align : top; + } + + td { + background : @main-background; + white-space : pre; + } + + td > dl { + border : 0; + padding : 0; + } + + dl, + pre, + label { + padding : 0; + } + + pre { + border-top : 0; + border-bottom : 0; + border-right : 0; + } + + label[for]:before { + display : none; + } + + th:first-child { + background : 0; + border : 0; + } + + td:first-child, + th { + font-weight : bold; + background : @secondary-background; + color : @variable-name-color; + } + + td.kint-empty { + background : #d33682 !important; + } + + tr:hover { + > td { + box-shadow : 0px 0px 1px 0px @border-color-hover inset; + } + + var { + color: @variable-type-color-hover; + } + + } +} + +// +// TRACE +// -------------------------------------------------- +.kint-trace { + .kint-source { + line-height : 1em + 0.02 * @spacing + } + + .kint-source span { + padding-right : 1px; + border-right : 3px inset @variable-type-color; + } + + .kint-source .kint-highlight { + background : @secondary-background; + } + + .kint-parent > b { + min-width : 18px; + display : inline-block; + text-align : right; + color : @variable-name-color; + } + + var { + margin-right : 5px; + } +} + +// +// MISC +// -------------------------------------------------- + +// keyboard navigation caret +.kint-focused { + .keyboard-caret +} + +.kint-color-preview { + box-shadow : 0 0 2px 0 #b6cedb; + height : 16px; + text-align : center; + text-shadow : -1px 0 #839496, 0 1px #839496, 1px 0 #839496, 0 -1px #839496; + width : 230px; + color : #fdf6e3; +} \ No newline at end of file diff --git a/app/lib/kint/view/less/index.html b/app/lib/kint/view/less/index.html new file mode 100644 index 0000000..c942a79 --- /dev/null +++ b/app/lib/kint/view/less/index.html @@ -0,0 +1,10 @@ + + +Directory access is forbidden.
+ + + \ No newline at end of file diff --git a/app/lib/kint/view/less/original.less b/app/lib/kint/view/less/original.less new file mode 100644 index 0000000..9da7ba9 --- /dev/null +++ b/app/lib/kint/view/less/original.less @@ -0,0 +1,49 @@ +@import "_kint.less"; + +@default-font: Consolas, "Courier New", monospace; +@spacing : 4; + +@main-background: #e0eaef; +@secondary-background : #c1d4df; + +@text-color: #1d1e1e; +@variable-name-color: #1d1e1e; +@variable-type-color: #0092db; +@variable-type-color-hover: #5cb730; + +@border-color: #b6cedb; +@border-color-hover: #0092db; + +@caret-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAA8CAMAAACO5hB7AAAACVBMVEX///82b4tctzBls0NMAAAAQklEQVR42rWRIQ4AAAgCwf8/2qgER2BeuwJsgAqIzekMfMryPL9XQSkobE6vwKcsz/N7FfPvh09lnPf/b+7673+f0uHuAZ/EdkNQAAAAAElFTkSuQmCC"); + +.keyboard-caret() { + box-shadow : 0 0 3px 2px #5cb730; +} + +.kint { + > dl > dt { + background : -webkit-linear-gradient(top, #e3ecf0 0, #c0d4df 100%); + background : linear-gradient(to bottom, #e3ecf0 0, #c0d4df 100%); + } + + ul.kint-tabs { + background : -webkit-linear-gradient(top, #9dbed0 0px, #b2ccda 100%); + background : linear-gradient(to bottom, #9dbed0 0px, #b2ccda 100%); + } + + &:not(.kint-trace) > dl > dd > ul.kint-tabs li { + background : @main-background; + &.kint-active-tab { + background : @secondary-background; + } + } + + &.kint-trace > dl > dt { + background : -webkit-linear-gradient(top, #c0d4df 0px, #e3ecf0 100%); + background : linear-gradient(to bottom, #c0d4df 0px, #e3ecf0 100%); + } + + .kint-source .kint-highlight { + background : #f0eb96; + } +} \ No newline at end of file diff --git a/app/lib/kint/view/less/solarized-dark.less b/app/lib/kint/view/less/solarized-dark.less new file mode 100644 index 0000000..0d1dc23 --- /dev/null +++ b/app/lib/kint/view/less/solarized-dark.less @@ -0,0 +1,37 @@ +@import "_kint.less"; + +@default-font: Consolas, "Courier New", monospace; +@spacing : 5; + +@main-background: #002b36; // base 03 +@secondary-background : #073642; // base 02 + +@text-color: #839496; // base 0 +@variable-name-color: #93a1a1; // base 1 +@variable-type-color: #268bd2; // blue +@variable-type-color-hover: #2aa198; // cyan + +@border-color: #586e75; // base 01 +@border-color-hover: #268bd2; // blue + +@caret-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAA8CAMAAACO5hB7AAAA7VBMVEVYbnWToaH///9YbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnWToaGToaGToaGToaGToaGToaGToaGToaGToaFYbnWToaFYbnVYbnWToaGToaFYbnWToaFYbnWToaFYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnWToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaFYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnWToaGToaGToaGToaGToaGToaGToaGToaGToaFYbnWToaEeRtj1AAAATXRSTlMAAACLab0B7iP2R7CL9iPuaUewAb36F0/QnPoX0JxPYQaurepi6QV8FhV7MzFhM6586RYFMa3qYnsVBpNQ+ZGOGJ3PkM9QkZAY+Y6TnV7gnYsAAAEcSURBVHhebdHVbgMxEEBRu8sUZmqapBBoSuGUmWb+/3NayxtrLOe+Hck745XZgd6/eb3CVcKt7HmR+gKxlCGOETG5vFbOoahR6NxI5zHt6nuq+2dqnqfzzH3mfcz70vb8H6MJt5u6a96hS30E4PjEFgAEp2fKNojKUfVEOoS044ex7u3YPE/nmfvM+5j3pe17T9oe/77O41w+n4vnrbrwZxbTshVhvtx5Kb8vliRLRWmeSQSTjJq/El5x5fUXYmNN9hcQC5y4g/hGvVksNtT8451rns2IScb7mn567ll2GNpWr9YWfvQgzWsKs8HOA/m960g6rjTzA8HAV/NHwiOmPLwDKA/J/gggYsRVgFvqbr/fpWYv90zzZKKs9Qfx00Jx65oxLAAAAABJRU5ErkJggg=="); + +.keyboard-caret() { + box-shadow : 0 0 3px 2px #859900 inset; // green + border-radius : 7px; +} + +body { + background : @secondary-background; + color : #fff; // for non-kint elements to remain at least semi-readable +} + +.kint { + background : @secondary-background; + box-shadow : 0 0 5px 3px @secondary-background; + + > dl > dt, + ul.kint-tabs { + box-shadow : 4px 0 2px -3px @variable-type-color inset; + } +} \ No newline at end of file diff --git a/app/lib/kint/view/less/solarized.less b/app/lib/kint/view/less/solarized.less new file mode 100644 index 0000000..9a76181 --- /dev/null +++ b/app/lib/kint/view/less/solarized.less @@ -0,0 +1,27 @@ +@import "_kint.less"; + +@default-font: Consolas, "Courier New", monospace; +@spacing : 5; + +@main-background: #fdf6e3; // base 3 +@secondary-background : #eee8d5; // base 2 + +@text-color: #657b83; // base 00 +@variable-name-color: #586e75; // base 01 +@variable-type-color: #268bd2; // blue +@variable-type-color-hover: #2aa198; // cyan + +@border-color: #93a1a1; // base 1 +@border-color-hover: #268bd2; // blue + +@caret-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAA8CAMAAACO5hB7AAAA7VBMVEVYbnWToaH///9YbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnWToaGToaGToaGToaGToaGToaGToaGToaGToaFYbnWToaFYbnVYbnWToaGToaFYbnWToaFYbnWToaFYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnWToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaGToaFYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnVYbnWToaGToaGToaGToaGToaGToaGToaGToaGToaFYbnWToaEeRtj1AAAATXRSTlMAAACLab0B7iP2R7CL9iPuaUewAb36F0/QnPoX0JxPYQaurepi6QV8FhV7MzFhM6586RYFMa3qYnsVBpNQ+ZGOGJ3PkM9QkZAY+Y6TnV7gnYsAAAEcSURBVHhebdHVbgMxEEBRu8sUZmqapBBoSuGUmWb+/3NayxtrLOe+Hck745XZgd6/eb3CVcKt7HmR+gKxlCGOETG5vFbOoahR6NxI5zHt6nuq+2dqnqfzzH3mfcz70vb8H6MJt5u6a96hS30E4PjEFgAEp2fKNojKUfVEOoS044ex7u3YPE/nmfvM+5j3pe17T9oe/77O41w+n4vnrbrwZxbTshVhvtx5Kb8vliRLRWmeSQSTjJq/El5x5fUXYmNN9hcQC5y4g/hGvVksNtT8451rns2IScb7mn567ll2GNpWr9YWfvQgzWsKs8HOA/m960g6rjTzA8HAV/NHwiOmPLwDKA/J/gggYsRVgFvqbr/fpWYv90zzZKKs9Qfx00Jx65oxLAAAAABJRU5ErkJggg=="); + +.keyboard-caret() { + box-shadow : 0 0 3px 2px #859900 inset; // green + border-radius : 7px; +} + +.kint > dl > dt, +.kint ul.kint-tabs { + box-shadow : 4px 0 2px -3px @variable-type-color inset; +} \ No newline at end of file diff --git a/app/lib/kint/view/trace.phtml b/app/lib/kint/view/trace.phtml new file mode 100644 index 0000000..3641862 --- /dev/null +++ b/app/lib/kint/view/trace.phtml @@ -0,0 +1,77 @@ + Kint::$enabled, + 'displayCalledFrom' => Kint::$displayCalledFrom, +); +Kint::$enabled = true; +Kint::$displayCalledFrom = false; + +echo '{$step['source']}
Directory access is forbidden.
+ + +