diff --git a/.config/config_global.php b/.config/config_global.php index b70856f..613f72b 100644 --- a/.config/config_global.php +++ b/.config/config_global.php @@ -98,5 +98,7 @@ define('DB_PASS', '2YcEOiFRUhk5ELeT9gZ3'); define('TBL_FRONT_NAVIGATION', 'ahd_navigation'); define('TBL_IMAGE_TEXT', 'ahd_image_text'); define('TBL_IMAGE', 'ahd_image'); +define('TBL_TEXT', 'ahd_text'); +define('TBL_SUBLINE', 'ahd_subline'); require_once(PATH_CNF . 'config_version.php'); \ No newline at end of file diff --git a/backend/editor/.config/editor_config.php b/backend/editor/.config/editor_config.php index 7a8d1d3..3fde2e1 100644 --- a/backend/editor/.config/editor_config.php +++ b/backend/editor/.config/editor_config.php @@ -10,7 +10,7 @@ $editor['name'] = 'AHD Allradhaus GmbH'; if (ENVIRONMENT === 'local') { - $editor['editorUrl'] = SCHEME . '://csteinle.ddns.net/rist-editors/'; + $editor['editorUrl'] = SCHEME . '://csteinle.ddnss.de/rist-editors/'; $editor['editorVersion'] = '2.0.0'; } elseif (ENVIRONMENT === 'production') @@ -22,10 +22,18 @@ $editor['webserviceUrl'] = HOST_URL . str_replace(PATH_ROOT, '', dirname(__DIR__ $editor['imageTypes'] = array('image/png', 'image/jpeg', 'image/gif'); $editor['imageDimension']['image'] = array('width' => 480, 'height' => null, 'standardImage' => HTML_IMG . 'standard_upload.jpg', 'quality' => 95); -$editor['imageDimension']['keyVisual'] = array('width' => 1368, 'height' => 342, 'standardImage' => HTML_IMG . 'standard_upload.jpg', 'quality' => 95, ); +$editor['imageDimension']['keyVisual'] = array('width' => 1368, 'height' => 342, 'standardImage' => HTML_IMG . 'header_upload.jpg', 'quality' => 95); $editor['imageDimension']['thumb'] = array('width' => 152, 'quality' => 90); -$editor['imageDimension']['orig'] = array('width' => 2560, 'height' => 2560, 'quality' => 97); +$editor['imageDimension']['orig'] = array('width' => 1920, 'height' => 1920, 'quality' => 93); $editor['contentElements'] = array('subline', 'text', 'textimage'); $editor['backendPrefix'] = PATH_PREFIX . '/' . str_replace(PATH_ROOT, '', dirname(__DIR__)); -$editor['backendUrl'] = HOST_URL . str_replace(PATH_ROOT, '', dirname(__DIR__)) . '/webservice/requestData.php'; \ No newline at end of file +$editor['backendUrl'] = HOST_URL . str_replace(PATH_ROOT, '', dirname(__DIR__)) . '/webservice/requestData.php'; + +$editor['linkReplacements'] = array('AHD'); +$editor['editorPrefix'] = 'ahd'; + +$editor['mediaPath'] = PATH_ROOT . 'media/' . $editor['editorPrefix'] . '/'; +$editor['mediaPrefix'] = HTML_MED . $editor['editorPrefix'] . '/'; + +$editor['fileExtensions'] = array('image/png' => 'png', 'image/jpeg' => 'jpg', 'image/gif' => 'gif'); diff --git a/backend/editor/index.php b/backend/editor/index.php index 001f5c4..b36f601 100644 --- a/backend/editor/index.php +++ b/backend/editor/index.php @@ -22,5 +22,6 @@ $loader = require PATH_ROOT . '/vendor/autoload.php'; $registry = \Helper\Registry::getInstance(); $registry->editorConfig = $editor; $registry->editorConfig['token'] = session_id(); +$registry->editorConfig['sessionLanguage'] = $_SESSION['lang']; $route = new \Route\FrontendRoute($siteID, true); \ No newline at end of file diff --git a/backend/editor/webservice/requestData.php b/backend/editor/webservice/requestData.php index 5326af1..cc49a78 100644 --- a/backend/editor/webservice/requestData.php +++ b/backend/editor/webservice/requestData.php @@ -6,22 +6,231 @@ * * @copyright CS medien- & kommunikationssysteme (http://www.steinle-computer.de) */ - +//file_put_contents(__DIR__ . '/request.log', var_export($_POST, true) . "\n\n", FILE_APPEND); +/** + * Fehlende Authentifizierung abfangen + */ if (!isset($_POST['token']) || !is_string($_POST['token']) || empty($_POST['token'])) { die(); } +$token = $_POST['token']; +unset($_POST['token']); -session_start($_POST['token']); +/** + * Fehlende SESSION abfangen + */ +session_start($token); if (!isset($_SESSION['userID']) || !is_numeric($_SESSION['userID']) || $_SESSION['userID'] < 1) { die(); } - if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) { die(); } -file_put_contents(__DIR__ . '/request.log', var_export($_POST, true) . "\n\n", FILE_APPEND); -echo json_encode(1); \ No newline at end of file +/** + * Fehlende Variablen abfangen + */ +if (!isset($_POST['request']) || $_POST['request'] === '') +{ + die(); +} +$request = $_POST['request']; +unset($_POST['request']); + +$pathRoot = dirname(dirname(dirname(__DIR__))) . '/'; + +require_once($pathRoot . '.config/config_global.php'); +require_once(dirname(__DIR__) . '/.config/editor_config.php'); +$loader = require PATH_ROOT . '/vendor/autoload.php'; + +$registry = Helper\Registry::getInstance(); +$registry->editorConfig = $editor; +if (isset($_POST['navID'])) +{ + $registry->navID = $_POST['navID']; +} + +$modelData = array(); +$dbData = $_POST; +switch ($request) +{ + case 'getText': + $modelData = Model\TextModel::getItem($dbData['ID']); + break; + + case 'updateText': + $dbData['text'] = Helper\Text::prepareText($dbData['text']); + $modelData = Model\TextModel::update($dbData); + break; + + case 'getSubline': + $modelData = Model\SublineModel::getItem($dbData['ID']); + break; + + case 'updateSubline': + $dbData['text'] = trim(str_replace(array('
';
-//var_dump(json_encode($array));
\ No newline at end of file
+$route = new \Route\FrontendRoute($url);
\ No newline at end of file
diff --git a/js/ahd.js b/js/ahd.js
new file mode 100644
index 0000000..2a06fed
--- /dev/null
+++ b/js/ahd.js
@@ -0,0 +1,367 @@
+/**
+ * Created by CS medien- & kommunikationssysteme.
+ * @author Christian Steinle
+ * @date 24.12.2016
+ *
+ * @copyright CS medien- & kommunikationssysteme (http://www.steinle-computer.de)
+ */
+
+$(document).ready(function () {
+ slider.init();
+ kenBurns.init();
+});
+
+$(window).resize(function () {
+ slider.initVariables();
+ kenBurns.initVariables();
+});
+
+var slider = {
+ interval: null,
+ displayTime: 4000,
+ animationTime: 400,
+
+ actualImageID: -1,
+ actualImage: null,
+ nextImageID: 0,
+ nextImage: null,
+ countImages: 0,
+
+ animationWidth: 0,
+ animationHeight: 0,
+
+ sliderElement: null,
+ sliderImages: null,
+
+ availableAnimations: [
+ 'left',
+ 'top',
+ 'width',
+ 'height',
+ 'opacity'
+ ],
+ animation: {},
+
+
+ init: function () {
+ slider.initElements();
+ slider.initVariables();
+ slider.interval = window.setInterval(slider.doAnimation, slider.displayTime);
+ },
+
+
+ initElements: function () {
+ slider.sliderElement = $('.slider');
+ slider.sliderImages = $('img', slider.sliderElement);
+ },
+
+
+ initVariables: function () {
+ slider.countImages = slider.sliderImages.length;
+ if (slider.countImages === 0) {
+ return false;
+ }
+ slider.animationWidth = slider.sliderElement.width();
+ slider.animationHeight = keyVisualData.height * slider.animationWidth / keyVisualData.width;
+ slider.sliderElement.css('height', slider.animationHeight);
+ slider.setNextImages();
+ },
+
+
+ setNextImages: function () {
+ ++slider.actualImageID;
+ ++slider.nextImageID;
+
+ if (slider.actualImageID === slider.countImages) {
+ slider.actualImageID = 0;
+ }
+
+ if (slider.nextImageID === slider.countImages) {
+ slider.nextImageID = 0;
+ }
+
+ slider.actualImage = $(slider.sliderImages[slider.actualImageID]);
+ slider.nextImage = $(slider.sliderImages[slider.nextImageID]);
+ },
+
+
+ doAnimation: function () {
+ if (slider.countImages < 2) {
+ return false;
+ }
+
+ var animationKey = Math.floor(Math.random() * slider.availableAnimations.length);
+ var animationName = slider.availableAnimations[animationKey];
+
+ slider.resetUnusedImages();
+
+ switch (animationName) {
+ case 'left':
+ slider.getShiftLeft();
+ break;
+ case 'top':
+ slider.getShiftTop();
+ break;
+ case 'width':
+ slider.getWidth();
+ break;
+ case 'height':
+ slider.getHeight();
+ break;
+ case 'opacity':
+ slider.getOpacity();
+ break;
+ default:
+ slider.getShiftLeft();
+ break;
+ }
+
+ slider.actualImage.show().animate(slider.animation.actual, slider.animationTime);
+ slider.nextImage.show().animate(slider.animation.next, slider.animationTime);
+
+ slider.setNextImages();
+ },
+
+ resetUnusedImages: function () {
+ slider.sliderImages.each(function (imageID, imageElement) {
+ var image = $(imageElement);
+
+ if (imageID !== slider.actualImageID && imageID !== slider.nextImageID) {
+ image.hide();
+ }
+
+ image.css({
+ left: 0,
+ top: 0,
+ width: slider.animationWidth,
+ height: slider.animationHeight,
+ opacity: 1
+ });
+
+ });
+ },
+
+
+ getShiftLeft: function () {
+ slider.nextImage.css({left: slider.animationWidth});
+ slider.animation.next = {left: 0};
+ slider.animation.actual = {left: -1 * slider.animationWidth, opacity: 0};
+ },
+
+
+ getShiftTop: function () {
+ slider.nextImage.css({top: slider.animationHeight});
+ slider.animation.next = {top: 0};
+ slider.animation.actual = {top: -1 * slider.animationHeight, opacity: 0};
+ },
+
+
+ getWidth: function () {
+ slider.nextImage.css({width: 0, left: slider.animationWidth / 2, opacity: 0});
+ slider.animation.next = {width: slider.animationWidth, left: 0, opacity: 1};
+ slider.animation.actual = {width: 0, left: slider.animationWidth / 2, opacity: 0};
+ },
+
+
+ getHeight: function () {
+ slider.nextImage.css({height: 0, top: slider.animationHeight / 2, opacity: 0});
+ slider.animation.next = {height: slider.animationHeight, top: 0, opacity: 1};
+ slider.animation.actual = {height: 0, top: slider.animationHeight / 2, opacity: 0};
+ },
+
+
+ getOpacity: function () {
+ slider.nextImage.css({opacity: 0});
+ slider.animation.next = {opacity: 1};
+ slider.animation.actual = {opacity: 0};
+ }
+};
+
+
+var kenBurns = {
+ interval: null,
+ displayTime: 5000,
+ animationTime: 400,
+ scaleFactor: 1.2,
+
+ actualImageID: -1,
+ actualImage: null,
+ nextImageID: 0,
+ nextImage: null,
+ countImages: 0,
+
+ animationWidth: 0,
+ animationHeight: 0,
+
+ kenBurnsElement: null,
+ kenBurnsImages: null,
+
+ animationParams: {},
+
+
+ init: function () {
+ kenBurns.initElements();
+ kenBurns.initVariables();
+ kenBurns.resetUnusedImages(true);
+ kenBurns.doAnimation();
+ kenBurns.interval = window.setInterval(kenBurns.doAnimation, kenBurns.displayTime);
+ },
+
+
+ initElements: function () {
+ kenBurns.kenBurnsElement = $('.kenburns');
+ kenBurns.kenBurnsImages = $('img', kenBurns.kenBurnsElement);
+ },
+
+
+ initVariables: function () {
+ kenBurns.countImages = kenBurns.kenBurnsImages.length;
+ if (kenBurns.countImages === 0) {
+ return false;
+ }
+ kenBurns.animationWidth = kenBurns.kenBurnsElement.width();
+ kenBurns.animationHeight = keyVisualData.height * kenBurns.animationWidth / keyVisualData.width;
+ kenBurns.kenBurnsElement.css('height', kenBurns.animationHeight);
+ kenBurns.setNextImages();
+ },
+
+
+ setNextImages: function () {
+ ++kenBurns.actualImageID;
+ ++kenBurns.nextImageID;
+
+ if (kenBurns.actualImageID === kenBurns.countImages) {
+ kenBurns.actualImageID = 0;
+ }
+
+ if (kenBurns.nextImageID === kenBurns.countImages) {
+ kenBurns.nextImageID = 0;
+ }
+
+ kenBurns.actualImage = $(kenBurns.kenBurnsImages[kenBurns.actualImageID]);
+ kenBurns.nextImage = $(kenBurns.kenBurnsImages[kenBurns.nextImageID]);
+ },
+
+
+ doAnimation: function () {
+ if (kenBurns.countImages < 2) {
+ return false;
+ }
+
+ kenBurns.resetUnusedImages(false);
+ kenBurns.getAnimationParams();
+
+ kenBurns.setNextImages();
+ },
+
+
+ resetUnusedImages: function (doAll) {
+ kenBurns.kenBurnsImages.each(function (imageID, imageElement) {
+ var image = $(imageElement);
+
+ if ((imageID !== kenBurns.actualImageID && imageID !== kenBurns.nextImageID) || doAll === true) {
+
+ var imageWidth = kenBurns.animationWidth;
+ var imageHeight = kenBurns.animationHeight;
+ if (image.data('zoom') === 'out') {
+ imageWidth = kenBurns.animationWidth * kenBurns.scaleFactor;
+ imageHeight = kenBurns.animationHeight * kenBurns.scaleFactor;
+ }
+
+ switch (image.data('start')) {
+ case 'nw' :
+ image.css({left: 0, top: 0, right: '', bottom: ''});
+ break;
+
+ case 'n':
+ image.css({left: (kenBurns.animationWidth - imageWidth) / 2, top: 0, right: '', bottom: ''});
+ break;
+
+ case 'ne':
+ image.css({left: '', top: 0, right: 0, bottom: ''});
+ break;
+
+ case 'e':
+ image.css({left: '', top: (kenBurns.animationHeight - imageHeight) / 2, right: 0, bottom: ''});
+ break;
+
+ case 'se':
+ image.css({left: '', top: '', right: 0, bottom: 0});
+ break;
+
+ case 's' :
+ image.css({left: (kenBurns.animationWidth - imageWidth) / 2, top: '', right: '', bottom: 0});
+ break;
+
+ case 'sw':
+ image.css({left: 0, top: '', right: '', bottom: 0});
+ break;
+
+ case 'w':
+ image.css({left: 0, top: (kenBurns.animationHeight - imageHeight) / 2, right: '', bottom: ''});
+ break;
+
+ case 'c':
+ image.css({
+ left: (kenBurns.animationWidth - imageWidth) / 2,
+ top: (kenBurns.animationHeight - imageHeight) / 2,
+ right: '',
+ bottom: ''
+ });
+ break;
+ }
+
+ image.css({width: imageWidth, height: imageHeight, opacity: 0, zIndex: 0});
+ }
+
+
+ });
+ },
+
+
+ getAnimationParams: function () {
+ var cssObject = {};
+ var image = kenBurns.actualImage;
+ image.css('zIndex', 1);
+ cssObject.width = kenBurns.animationWidth;
+ cssObject.height = kenBurns.animationHeight;
+ if (image.data('zoom') === 'in') {
+ cssObject.width = kenBurns.animationWidth * kenBurns.scaleFactor;
+ cssObject.height = kenBurns.animationHeight * kenBurns.scaleFactor;
+ }
+
+ switch (image.data('start')) {
+ case 'n':
+ cssObject.left = (kenBurns.animationWidth - cssObject.width) / 2;
+ break;
+
+ case 'e':
+ cssObject.top = (kenBurns.animationHeight - cssObject.height) / 2;
+ break;
+
+ case 's' :
+ cssObject.left = (kenBurns.animationWidth - cssObject.width) / 2;
+ break;
+
+ case 'w':
+ cssObject.top = (kenBurns.animationHeight - cssObject.height) / 2;
+ break;
+
+ case 'c':
+ cssObject.left = (kenBurns.animationWidth - cssObject.width) / 2;
+ cssObject.top = (kenBurns.animationHeight - cssObject.height) / 2;
+ break;
+ }
+
+ cssObject.opacity = 4;
+
+ image.animate(
+ cssObject
+ , 7000, 'swing', function () {
+ image.animate({
+ opacity: 0
+ }, 1000, 'swing')
+ })
+ }
+
+};
\ No newline at end of file
diff --git a/js/npm.js b/js/npm.js
deleted file mode 100644
index bf6aa80..0000000
--- a/js/npm.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
-require('../../js/transition.js')
-require('../../js/alert.js')
-require('../../js/button.js')
-require('../../js/carousel.js')
-require('../../js/collapse.js')
-require('../../js/dropdown.js')
-require('../../js/modal.js')
-require('../../js/tooltip.js')
-require('../../js/popover.js')
-require('../../js/scrollspy.js')
-require('../../js/tab.js')
-require('../../js/affix.js')
\ No newline at end of file
diff --git a/rendering/Controller/FrontendController.php b/rendering/Controller/FrontendController.php
index 359090a..14f29d5 100644
--- a/rendering/Controller/FrontendController.php
+++ b/rendering/Controller/FrontendController.php
@@ -10,6 +10,7 @@
namespace Controller;
use Helper\Database;
+use Helper\Registry;
use Model\NavigationModel;
use View\NavigationView;
use View\StandardView;
@@ -45,19 +46,18 @@ class FrontendController
$navigation->setEditable($this->isEditable);
$navigation->init();
+ $registry = Registry::getInstance();
+ $registry->navID = NavigationModel::getActiveNavID();
+ $registry->navigationPath = NavigationModel::getNavigationPath();
+
$this->contents['title'] = NavigationModel::getTitle();
$this->contents['navigation'] = $navigation->render();
$this->contents['headline'] = NavigationModel::getHeadline();
- $this->contents['navID'] = NavigationModel::getActiveNavID();
$this->contents['content'] = '';
- $this->contents['keyVisual'] = '';
- $tmpKeyVisual = NavigationModel::getKeyVisual();
- foreach ($tmpKeyVisual as $data)
- {
- $this->contents['keyVisual'] .= $this->buildContents($data);
- }
+ $keyVisual = NavigationModel::getKeyVisual();
+ $this->contents['keyVisual'] = $this->buildContents($keyVisual);
$tmpContents = NavigationModel::getContents();
/**
@@ -80,9 +80,18 @@ class FrontendController
*/
protected function buildContents(array $data)
{
+ /**
+ * Abfangen von nicht behandelbaren Abfragen durch den mod_rewrite
+ * z.B. nicht vorhandene Bilder
+ */
+ if (!isset($data['Controller']))
+ {
+ return '';
+ }
/**
* @var Database $modelClass
*/
+ $modelData = array();
$modelClass = 'Model\\' . $data['Controller'] . 'Model';
$viewClass = 'View\\' . $data['Controller'] . 'View';
if (class_exists($modelClass, true))
@@ -99,7 +108,6 @@ class FrontendController
$modelClass::setFilter($data['IDs']);
$modelData = $modelClass::getIndex();
$modelData = array_merge($modelData, $tmpModelData);
- $modelData['navID'] = $this->contents['navID'];
}
}
else
@@ -109,6 +117,13 @@ class FrontendController
*/
return '';
}
+ if (empty($modelData))
+ {
+ /**
+ * TODO: ErrorHandler bauen
+ */
+ return '';
+ }
if (class_exists($viewClass, true))
{
$dataView = new $viewClass($modelData, $data['Controller']);
diff --git a/rendering/Helper/Database.php b/rendering/Helper/Database.php
index a822bd4..264e193 100644
--- a/rendering/Helper/Database.php
+++ b/rendering/Helper/Database.php
@@ -36,6 +36,19 @@ class Database
*/
static $filter = '1=1';
+ /**
+ * Die Beziehung einer Datenbank-Tabelle zu einer anderen
+ * $relations = array(
+ * 0 => array(
+ * 'ownKey' => 'Spaltenname der eigenen Tabelle',
+ * 'foreignTable' => 'Tabellenname der "Fremd"-Tabelle',
+ * 'foreignKey' => 'Spaltenname der "Fremd"-Tabelle
+ * ),
+ * );
+ * @var array
+ */
+ static $relations = array();
+
/**
* Hier werden die Daten von getIndex() gespeichert
* @var array
@@ -48,18 +61,68 @@ class Database
protected static $db = null;
+ /**
+ * Konstruktor schützen, weil Singleton
+ * @author Christian Steinle
+ */
protected function __construct()
{
}
-
- protected function __clone()
+ /**
+ * Liefert ein mehrdimensionales, assoziatives Array mit allen Datensätzen, die zum Filter passen
+ * als Schlüssel der ersten Dimension dient der Wert des Primär-Schlüssels der Datenbank-Tabelle
+ * Legt alle Daten in self::$data ab
+ * @author Christian Steinle
+ *
+ * @see self::query()
+ * @see self::$data
+ *
+ * TODO: getIndex für static::$relations analog zu getItem
+ *
+ * @return array
+ */
+ final public static function getIndex()
{
+ static::setRelations();
+ $sql = 'SELECT * FROM ' . static::TBL_NAME . ' WHERE ' . static::$filter . ' ' . static::ORDER_BY . ';';
+ self::$data = self::query($sql);
+ return self::$data;
}
+ /**
+ * Setzt die Variable zur Verbindung verschiedener Datenbank-Tabellen
+ */
+ public static function setRelations()
+ {
+ static::$relations = array();
+ }
+
+ /**
+ * Liefert ein mehrdimensionales, assoziatives Array mit allen Datensätzen, die zum SQL-Query passen
+ * als Schlüssel der ersten Dimension dient der Wert des Primär-Schlüssels der Datenbank-Tabelle
+ * @author Christian Steinle
+ *
+ * @param string $sql
+ * @return array
+ */
+ final protected static function query($sql)
+ {
+ self::getInstance();
+ $result = self::$db->query($sql);
+ $data = array();
+
+ while ($tmpData = $result->fetch_assoc())
+ {
+ $data[$tmpData[static::PRIMARY_KEY]] = $tmpData;
+ }
+
+ return $data;
+ }
/**
* Stellt die Datenbank-Verbindung her
+ * @author Christian Steinle
*
* return void
*/
@@ -72,56 +135,254 @@ class Database
}
}
+ /**
+ * Macht das Update für den Eintrag in einer Datenbank-Tabelle
+ * @author Christian Steinle
+ *
+ * @param array $request
+ * @return int
+ */
+ final public static function update(array $request)
+ {
+ static::beforeUpdate($request);
+ static::setRelations();
+
+ /**
+ * @var Database $class
+ */
+ foreach (static::$relations as $relation)
+ {
+ $class = $relation['foreignModel'];
+ $request[$relation['ownKey']] = $class::update($request);
+ }
+
+
+ $primaryKey = intval($request[static::PRIMARY_KEY]);
+ unset($request[static::PRIMARY_KEY]);
+
+ $model = self::queryModel(static::TBL_NAME, true);
+ $updateData = array();
+
+ foreach ($request as $fieldName => $fieldValue)
+ {
+ if (in_array($fieldName, $model))
+ {
+ $updateData[] = $fieldName . ' = "' . self::$db->real_escape_string($fieldValue) . '"';
+ }
+ }
+
+ if (empty($updateData))
+ {
+ return -1;
+ }
+
+ $sql = 'UPDATE ' . static::TBL_NAME . ' SET ' . implode(', ', $updateData) . ' WHERE ' . static::PRIMARY_KEY . ' = ' . $primaryKey . ' LIMIT 1;';
+ $result = self::$db->query($sql);
+ if ($result !== true)
+ {
+ return -1;
+ }
+
+ return $primaryKey;
+ }
+
+ /**
+ * Liefert die Spalten einer Datenbank-Tabelle
+ * @author Christian Steinle
+ *
+ * @param string $tableName
+ * @param bool $fieldsOnly
+ * @return array
+ */
+ final protected static function queryModel($tableName, $fieldsOnly = false)
+ {
+ self::getInstance();
+ $sql = 'SHOW COLUMNS FROM ' . $tableName . ';';
+ $result = self::$db->query($sql);
+ $data = array();
+
+ while ($tmpData = $result->fetch_assoc())
+ {
+ if ($fieldsOnly === true)
+ {
+ $data[] = $tmpData['Field'];
+ }
+ else
+ {
+ $data[] = $tmpData;
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Schreibt einen neuen Eintrag in einer Datenbank-Tabelle
+ * @author Christian Steinle
+ *
+ * @param array $request
+ * @return int
+ */
+ final public static function insert(array $request)
+ {
+ static::beforeInsert($request);
+ static::setRelations();
+
+ /**
+ * @var Database $class
+ */
+ foreach (static::$relations as $relation)
+ {
+ $class = $relation['foreignModel'];
+ $request[$relation['ownKey']] = $class::insert($request);
+ }
+
+ $model = self::queryModel(static::TBL_NAME, true);
+ $updateData = array();
+
+ foreach ($request as $fieldName => $fieldValue)
+ {
+ if (in_array($fieldName, $model))
+ {
+ $updateData[$fieldName] = '"' . self::$db->real_escape_string($fieldValue) . '"';
+ }
+ }
+
+ if (empty($updateData))
+ {
+ return -1;
+ }
+
+ $keys = implode(', ', array_keys($updateData));
+ $values = implode(', ', $updateData);
+ $sql = 'INSERT INTO ' . static::TBL_NAME . ' (' . $keys . ') VALUES (' . $values . ');';
+ $result = self::$db->query($sql);
+
+ if ($result !== true)
+ {
+ return -1;
+ }
+
+ return self::$db->insert_id;
+ }
+
+ /**
+ * Entfernt einen Eintrag aus einer Datenbank-Tabelle
+ * @author Christian Steinle
+ *
+ * @param int $id
+ * @return int
+ */
+ final public static function delete($id)
+ {
+ static::beforeDelete($id);
+ static::setRelations();
+
+ if (!empty(static::$relations))
+ {
+ $data = static::getItem($id);
+
+ /**
+ * @var Database $class
+ */
+ foreach (static::$relations as $relation)
+ {
+ $class = $relation['foreignModel'];
+ $relationID = intval($data[$relation['foreignKey']]);
+ $class::delete($relationID);
+ }
+ }
+
+ $query = 'DELETE FROM ' . static::TBL_NAME . ' WHERE ' . static::PRIMARY_KEY . ' = ' . $id . ' LIMIT 1;';
+ $result = self::$db->query($query);
+
+ return (($result) ? 1 : 0);
+ }
/**
* Liefert ein assoziatives Array des Datensatzes mit der übergebenen ID
+ * @author Christian Steinle
*
* @param int $id
* @return array
*/
final public static function getItem($id)
{
- $sql = 'SELECT * FROM ' . static::TBL_NAME . ' WHERE ' . static::PRIMARY_KEY . ' = ' . $id . ';';
+ static::setRelations();
+
+ if (empty(static::$relations))
+ {
+ $sql = 'SELECT * FROM ' . static::TBL_NAME . ' WHERE ' . static::PRIMARY_KEY . ' = ' . $id . ';';
+ }
+ else
+ {
+ $tables = array(static::TBL_NAME);
+ $matches = array();
+ foreach (static::$relations as $relation)
+ {
+ $class = $relation['foreignModel'];
+ $tables[] = $class::TBL_NAME;
+ $matches[] = static::TBL_NAME . '.' . $relation['ownKey'] . ' = ' . $class::TBL_NAME . '.' . $relation['foreignKey'];
+ }
+
+ $sql = 'SELECT * FROM ' . implode(', ', $tables) . ' WHERE ' . static::PRIMARY_KEY . ' = ' . $id . ' AND ' . implode(' AND ', $matches);
+ }
+
$data = self::query($sql);
return (!is_array($data) || empty($data)) ? array() : current($data);
}
/**
- * Liefert ein mehrdimensionales, assoziatives Array mit allen Datensätzen, die zum Filter passen
- * als Schlüssel der ersten Dimension dient der Wert des Primär-Schlüssels der Datenbank-Tabelle
- * Legt alle Daten in self::$data ab
+ * Setzt den Filter für die Datenbank zur späteren Verwendung
+ * @author Christian Steinle
*
- * @see self::query()
- * @see self::$data
- *
- * @return array
+ * @param string $filter
*/
- final public static function getIndex()
+ public static function setFilter($filter)
{
- $sql = 'SELECT * FROM ' . static::TBL_NAME . ' WHERE ' . static::$filter . ' ' . static::ORDER_BY . ';';
- self::$data = self::query($sql);
- return self::$data;
+ static::$filter = $filter;
}
/**
- * Liefert ein mehrdimensionales, assoziatives Array mit allen Datensätzen, die zum SQL-Query passen
- * als Schlüssel der ersten Dimension dient der Wert des Primär-Schlüssels der Datenbank-Tabelle
+ * Funktion, die vor dem Erstellen eines Datenbank-Eintrags ausgeführt wird
+ * @author Christian Steinle
*
- * @param string $sql
- * @return array
+ * @param array $request
*/
- final protected static function query($sql)
+ protected static function beforeInsert(array &$request)
{
- self::getInstance();
- $result = self::$db->query($sql);
- $data = array();
- while ($tmpData = $result->fetch_assoc())
- {
- $data[$tmpData[static::PRIMARY_KEY]] = $tmpData;
- }
+ }
- return $data;
+
+ /**
+ * Funktion, die vor dem Löschen eines Datenbank-Eintrags ausgeführt wird
+ * @author Christian Steinle
+ *
+ * @param int $id
+ */
+ protected static function beforeDelete($id)
+ {
+ }
+
+
+ /**
+ * Funktion, die vor dem Update eines Datenbank-Eintrags ausgeführt wird
+ * @author Christian Steinle
+ *
+ * @param array $request
+ */
+ protected static function beforeUpdate(array &$request)
+ {
+ }
+
+
+ /**
+ * Schützen, um das Klonen des Singletons zu vermeiden
+ * @author Christian Steinle
+ */
+ final protected function __clone()
+ {
}
}
\ No newline at end of file
diff --git a/rendering/Helper/Text.php b/rendering/Helper/Text.php
new file mode 100644
index 0000000..2e01ef0
--- /dev/null
+++ b/rendering/Helper/Text.php
@@ -0,0 +1,23 @@
+/', '', $text, 1));
+ $text = preg_replace('/>p\/', '', strrev($text), 1);
+ $text = strrev($text);
+ return $text;
+ }
+}
\ No newline at end of file
diff --git a/rendering/Model/ImageModel.php b/rendering/Model/ImageModel.php
index 902ed5d..4a418ba 100644
--- a/rendering/Model/ImageModel.php
+++ b/rendering/Model/ImageModel.php
@@ -11,13 +11,359 @@ namespace Model;
use Helper\Database;
+use Helper\Registry;
class ImageModel extends Database
{
const TBL_NAME = TBL_IMAGE;
- const PRIMARY_KEY = 'ID';
+ const PRIMARY_KEY = 'imageID';
const ORDER_BY = '';
+ /**
+ * Erzeugt die benötigten Bilder im Medien-Pfad und bereitet den Request auf
+ * @author Christian Steinle
+ *
+ * @param array $request
+ */
+ protected static function beforeInsert(array &$request)
+ {
+ if (isset($request['imageTextModel']) && $request['imageTextModel'] === true)
+ {
+ return;
+ }
+
+ $registry = Registry::getInstance();
+ $navID = $request['navID'];
+ unset($request['navID']);
+
+ $mediaPath = $registry->editorConfig['mediaPath'] . $navID . '/';
+ if (!is_dir($mediaPath))
+ {
+ mkdir($mediaPath, 0775, true);
+ }
+
+ ImageModel::createOrigImage($mediaPath, $request);
+ ImageModel::createWebImage($mediaPath, $request, 'keyVisual');
+ }
+
+ /**
+ * Erzeugt einen Unique-Filename in einem vorgegebenen Pfad
+ * @author Christian Steinle
+ * @param string $path
+ * @param string $filename
+ * @return string
+ */
+ public static function getUniqueFilename($path, $filename)
+ {
+ $filenameArray = self::filenameToArray($filename);
+ $filesInPath = glob($path . $filenameArray['filename'] . '*_orig.' . $filenameArray['extension']);
+ if (count($filesInPath) === 0)
+ {
+ return $filenameArray['filename'];
+ }
+ else
+ {
+ $newFilename = $filenameArray['filename'] . '_' . count($filesInPath);
+ return $newFilename;
+ }
+ }
+
+ /**
+ * Liefert ein Array zum übergebenen Dateinamen
+ * - 'filename' => Dateiname ohne Erweiterung
+ * - 'extension' => Datei-Erweiterung
+ * @author Christian Steinle
+ *
+ * @param string $filename
+ * @return array
+ */
+ public static function filenameToArray($filename)
+ {
+ $tmpData = explode('.', $filename, -1);
+ $newFilename = implode('.', $tmpData);
+ $extension = str_replace($newFilename . '.', '', $filename);
+ return array('filename' => $newFilename, 'extension' => $extension);
+ }
+
+ /**
+ * Kopiert das Standard-Bild oder -KeyVisual
+ * @author Christian Steinle
+ *
+ * @param string $newPath
+ * @param string $filename
+ * @param string $type
+ */
+ public static function copyStandardImage($newPath, $filename, $type)
+ {
+ $registry = Registry::getInstance();
+ switch ($type)
+ {
+ case 'image':
+ $imageData = $registry->editorConfig['imageDimension']['image'];
+ break;
+
+ case 'keyVisual':
+ $imageData = $registry->editorConfig['imageDimension']['keyVisual'];
+ break;
+
+ default:
+ return;
+ }
+
+ if (!is_dir($newPath))
+ {
+ mkdir($newPath, 0777, true);
+ }
+
+ $standardImagePath = substr(str_replace(PATH_PREFIX, '', PATH_ROOT), 0, -1) . $imageData['standardImage'];
+ $filenameArray = self::filenameToArray($filename);
+
+ copy($standardImagePath, $newPath . $filename);
+ copy($standardImagePath, $newPath . $filenameArray['filename'] . '_orig.' . $filenameArray['extension']);
+ self::createThumb($newPath, $filename);
+ }
+
+ /**
+ * Erstellt ein Thumbnail von einem Bild
+ * @author Christian Steinle
+ *
+ * @param string $path
+ * @param string $file
+ */
+ public static function createThumb($path, $file)
+ {
+ $registry = Registry::getInstance();
+ $imageData = $registry->editorConfig['imageDimension']['thumb'];
+ $newWidth = $imageData['width'];
+ $newQuality = $imageData['quality'];
+ $filenameArray = self::filenameToArray($file);
+
+ list($width, $height) = getimagesize($path . $file);
+ $newHeight = $height * $newWidth / $width;
+
+ $newImage = imagecreatetruecolor($newWidth, $newHeight);
+ switch ($filenameArray['extension'])
+ {
+ case 'jpg':
+ $origImage = imagecreatefromjpeg($path . $file);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagejpeg($newImage, $path . $filenameArray['filename'] . '_thumb.jpg', $newQuality);
+ break;
+
+ case 'png':
+ $origImage = imagecreatefrompng($path . $file);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagepng($newImage, $path . $filenameArray['filename'] . '_thumb.png');
+ break;
+
+ case 'gif':
+ $origImage = imagecreatefromgif($path . $file);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagegif($newImage, $path . $filenameArray['filename'] . '_thumb.gif');
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ /**
+ * Löscht vorhandene Bilder vor entfernen aus der Datenbank
+ * @author Christian Steinle
+ *
+ * @param int $id
+ */
+ protected static function beforeDelete($id)
+ {
+ $registry = Registry::getInstance();
+ $data = self::getItem($id);
+
+ $mediaPath = $registry->editorConfig['mediaPath'] . $registry->navID . '/';
+ ImageModel::deleteImages($mediaPath, $data['imageName'], $data['imageExtension']);
+ }
+
+ /**
+ * Löscht die Bilder aus dem Medienpfad
+ * @author Christian Steinle
+ *
+ * @param $mediaPath
+ * @param $imageName
+ * @param $imageExtension
+ */
+ public static function deleteImages($mediaPath, $imageName, $imageExtension)
+ {
+ unlink($mediaPath . $imageName . '.' . $imageExtension);
+ unlink($mediaPath . $imageName . '_orig.' . $imageExtension);
+ unlink($mediaPath . $imageName . '_thumb.' . $imageExtension);
+ }
+
+ /**
+ * Verschiebt / Erzeugt Bilder und generiert Derivate
+ * @author Christian Steinle
+ *
+ * @param array $request
+ */
+ protected static function beforeUpdate(array &$request)
+ {
+ $registry = Registry::getInstance();
+ $mediaPath = $registry->editorConfig['mediaPath'] . $registry->navID . '/';
+
+ $imageType = 'image';
+ if (isset($request['keyVisualID']))
+ {
+ $imageType = 'keyVisual';
+ }
+
+ $oldData = self::getItem($request[static::PRIMARY_KEY]);
+
+ if (isset($_FILES['changeUploadFile']) && $_FILES['changeUploadFile']['tmp_name'] !== '' && $_FILES['changeUploadFile']['error'] === 0)
+ {
+ ImageModel::deleteImages($mediaPath, $oldData['imageName'], $oldData['imageExtension']);
+ $request['imageName'] = ImageModel::getUniqueFilename($mediaPath, $request['imageName'] . '.' . $request['imageExtension']);
+ ImageModel::createOrigImage($mediaPath, $request);
+ ImageModel::createWebImage($mediaPath, $request, $imageType);
+ }
+ elseif (isset($_FILES['changeUploadFile']) && $_FILES['changeUploadFile']['tmp_name'] === '' && $oldData['imageName'] !== $request['imageName'])
+ {
+ $request['imageName'] = ImageModel::getUniqueFilename($mediaPath, $request['imageName'] . '.' . $request['imageExtension']);
+ rename($mediaPath . $oldData['imageName'] . '_orig.' . $oldData['imageExtension'], $mediaPath . $request['imageName'] . '_orig.' . $request['imageExtension']);
+ rename($mediaPath . $oldData['imageName'] . '.' . $oldData['imageExtension'], $mediaPath . $request['imageName'] . '.' . $request['imageExtension']);
+ rename($mediaPath . $oldData['imageName'] . '_thumb.' . $oldData['imageExtension'], $mediaPath . $request['imageName'] . '_thumb.' . $request['imageExtension']);
+ }
+
+ if (isset($_FILES['changeUploadFile']) &&
+ $_FILES['changeUploadFile']['tmp_name'] === '' &&
+ (abs($oldData['imageTop'] - $request['imageTop']) > .5 ||
+ abs($oldData['imageLeft'] - $request['imageLeft']) > .5 ||
+ abs($oldData['imageHeight'] - $request['imageHeight']) > .5 ||
+ abs($oldData['imageWidth'] - $request['imageWidth']) > .5)
+ )
+ {
+ unlink($mediaPath . $request['imageName'] . '.' . $request['imageExtension']);
+ unlink($mediaPath . $request['imageName'] . '_thumb.' . $request['imageExtension']);
+ ImageModel::createWebImage($mediaPath, $request, $imageType);
+ }
+ }
+
+ /**
+ * Legt ein hochgeladenes Bild im Medienpfad ab und verkleinert es, falls die Abmessungen zu groß sind
+ * @author Christian Steinle
+ *
+ * @param $mediaPath
+ * @param $request
+ */
+ public static function createOrigImage($mediaPath, &$request)
+ {
+ $registry = Registry::getInstance();
+ $origData = $registry->editorConfig['imageDimension']['orig'];
+
+ $tmpName = $request['imageName'] . '__tmp__.' . $request['imageExtension'];
+
+ if (!is_dir($mediaPath))
+ {
+ mkdir($mediaPath, 0777, true);
+ }
+
+ move_uploaded_file($_FILES['changeUploadFile']['tmp_name'], $mediaPath . $tmpName);
+
+ list($width, $height) = getimagesize($mediaPath . $tmpName);
+ if ($width > $origData['width'] || $height > $origData['height'])
+ {
+ $newWidth = $origData['width'];
+ $newHeight = $height * $newWidth / $width;
+
+ $newImage = imagecreatetruecolor($newWidth, $newHeight);
+ switch ($request['imageExtension'])
+ {
+ case 'jpg':
+ $origImage = imagecreatefromjpeg($mediaPath . $tmpName);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagejpeg($newImage, $mediaPath . $request['imageName'] . '_orig.jpg', $origData['quality']);
+ break;
+
+ case 'png':
+ $origImage = imagecreatefrompng($mediaPath . $tmpName);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagepng($newImage, $mediaPath . $request['imageName'] . '_orig.png');
+ break;
+
+ case 'gif':
+ $origImage = imagecreatefromgif($mediaPath . $tmpName);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagegif($newImage, $mediaPath . $request['imageName'] . '_orig.gif');
+ break;
+
+ default:
+ return;
+ }
+
+ unlink($mediaPath . $tmpName);
+ }
+ else
+ {
+ rename($mediaPath . $tmpName, $mediaPath . $request['imageName'] . '_orig.' . $request['imageExtension']);
+ }
+ }
+
+ /**
+ * Erzeugt das WebImage mit dem passenden Ausschnitt aus dem Original
+ * @author Christian Steinle
+ * TODO: Transparenz bei pngs
+ *
+ * @param $mediaPath
+ * @param $request
+ * @param $type
+ */
+ public static function createWebImage($mediaPath, $request, $type)
+ {
+ $registry = Registry::getInstance();
+ switch ($type)
+ {
+ case 'image':
+ $imageData = $registry->editorConfig['imageDimension']['image'];
+ break;
+
+ case 'keyVisual':
+ $imageData = $registry->editorConfig['imageDimension']['keyVisual'];
+ break;
+
+ default:
+ return;
+ }
+
+ $origName = $request['imageName'] . '_orig.' . $request['imageExtension'];
+ $webName = $request['imageName'] . '.' . $request['imageExtension'];
+ list($width, $height) = getimagesize($mediaPath . $origName);
+ $newWidth = $imageData['width'];
+ $newHeight = $newWidth * $request['imageHeight'] / $request['imageWidth'];
+
+ $newImage = imagecreatetruecolor($newWidth, $newHeight);
+ switch ($request['imageExtension'])
+ {
+ case 'jpg':
+ $origImage = imagecreatefromjpeg($mediaPath . $origName);
+ imagecopyresampled($newImage, $origImage, 0, 0, $request['imageLeft'] * $width / $newWidth, $request['imageTop'] * $width / $newWidth, $newWidth, $newHeight, $width * $request['imageWidth'] / $newWidth, $width * $request['imageWidth'] * $newHeight / ($newWidth * $newWidth));
+ imagejpeg($newImage, $mediaPath . $webName, $imageData['quality']);
+ break;
+
+ case 'png':
+ $origImage = imagecreatefrompng($mediaPath . $origName);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagepng($newImage, $mediaPath . $webName);
+ break;
+
+ case 'gif':
+ $origImage = imagecreatefromgif($mediaPath . $origName);
+ imagecopyresampled($newImage, $origImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
+ imagegif($newImage, $mediaPath . $webName);
+ break;
+
+ default:
+ return;
+ }
+
+ self::createThumb($mediaPath, $webName);
+ }
}
\ No newline at end of file
diff --git a/rendering/Model/ImageTextModel.php b/rendering/Model/ImageTextModel.php
index dae5c40..6201fc5 100644
--- a/rendering/Model/ImageTextModel.php
+++ b/rendering/Model/ImageTextModel.php
@@ -11,10 +11,65 @@ namespace Model;
use Helper\Database;
+use Helper\Registry;
class ImageTextModel extends Database
{
const TBL_NAME = TBL_IMAGE_TEXT;
- const PRIMARY_KEY = 'ID';
+ const PRIMARY_KEY = 'imageTextID';
+
+
+ /**
+ * Setzt die Relationen zu anderen Modellen
+ * @author Christian Steinle
+ */
+ public static function setRelations()
+ {
+ static::$relations = array(
+ 0 => array(
+ 'ownKey' => 'imageID',
+ 'foreignModel' => 'Model\\ImageModel',
+ 'foreignKey' => 'imageID'
+ )
+ );
+ }
+
+
+ /**
+ * Erzeugt die benötigten Bilder im Medien-Pfad und bereitet den Request auf
+ * @author Christian Steinle
+ *
+ * @param array $request
+ */
+ protected static function beforeInsert(array &$request)
+ {
+ $registry = Registry::getInstance();
+ $imageData = $registry->editorConfig['imageDimension']['image'];
+ $standardImagePath = substr(str_replace(PATH_PREFIX, '', PATH_ROOT), 0, -1) . $imageData['standardImage'];
+ $navID = $request['navID'];
+ unset($request['navID']);
+
+ $mediaPath = $registry->editorConfig['mediaPath'] . $navID . '/';
+ if (!is_dir($mediaPath))
+ {
+ mkdir($mediaPath, 0775, true);
+ }
+
+ $filename = end(explode('/', $standardImagePath));
+ $newFilename = ImageModel::getUniqueFilename($mediaPath, $filename);
+ $fileArray = ImageModel::filenameToArray($filename);
+ $request['imageOrigName'] = $fileArray['filename'];
+ $request['imageExtension'] = $fileArray['extension'];
+ $request['imageName'] = $newFilename;
+ list($width, $height) = getimagesize($standardImagePath);
+ $request['imageTop'] = 0;
+ $request['imageLeft'] = 0;
+ $request['imageHeight'] = $height;
+ $request['imageWidth'] = $width;
+ $request['imageTextModel'] = true;
+ ImageModel::copyStandardImage($mediaPath, $newFilename . '.' . $fileArray['extension'], 'image');
+ }
+
+
}
\ No newline at end of file
diff --git a/rendering/Model/NavigationModel.php b/rendering/Model/NavigationModel.php
index 3bd07fa..aa33818 100644
--- a/rendering/Model/NavigationModel.php
+++ b/rendering/Model/NavigationModel.php
@@ -12,6 +12,7 @@ namespace Model;
use Helper\Database;
+use Helper\Registry;
class NavigationModel extends Database
{
@@ -39,6 +40,8 @@ class NavigationModel extends Database
/**
* Setzt später benötigte Variablen für den FrontendController, so dass die Datenmodelle und die Views instanziiert werden können
+ * @author Christian Steinle
+ *
* @param array $routeParts
* @param bool $isEditable
*/
@@ -56,6 +59,13 @@ class NavigationModel extends Database
}
+ /**
+ * Initialisierung für das Backend ohne ModRewrite
+ * @author Christian Steinle
+ *
+ * @param int $siteID
+ * @param int $depth
+ */
protected static function initBackend($siteID, $depth)
{
foreach (self::$data as $navID => $navItem)
@@ -74,6 +84,9 @@ class NavigationModel extends Database
}
/**
+ * Umbau der Datenbank-Tabellenwerte in ein Mehrdimensionales Array
+ * @author Christian Steinle
+ *
* @param string $navKeyVisual
*/
protected static function initKeyVisual($navKeyVisual)
@@ -89,6 +102,9 @@ class NavigationModel extends Database
}
/**
+ * Umbau der Datenbank-Tabellenwerte in ein Mehrdimensionales Array
+ * @author Christian Steinle
+ *
* @param string $navContents
*/
protected static function initContent($navContents)
@@ -103,6 +119,11 @@ class NavigationModel extends Database
}
}
+
+ /**
+ * Baut den Navigationspfad als Array
+ * @author Christian Steinle
+ */
protected static function buildNavigationPath()
{
$navStart = $navStartPath[] = self::$activeNavID;
@@ -110,13 +131,22 @@ class NavigationModel extends Database
{
$navStart = $navStartPath[] = self::$data[$navStart]['navStart'];
}
+ $navStartPath[] = '0';
array_pop($navStartPath);
self::$navigationPath = array_reverse($navStartPath);
}
+
+ /**
+ * Initialisiert das Frontend unter Verwendung des ModRewrites
+ * @author Christian Steinle
+ *
+ * @param array $routeParts
+ */
protected static function initFrontend(array $routeParts)
{
$navStart = 0;
+ self::$navigationPath[] = 0;
foreach ($routeParts as $navLink)
{
foreach (self::$data as $navID => $navItem)
@@ -134,7 +164,10 @@ class NavigationModel extends Database
}
}
+
/**
+ * Liefert den Navigationspfad als Array
+ *
* @return array
*/
public static function getNavigationPath()
@@ -144,6 +177,8 @@ class NavigationModel extends Database
/**
+ * Liefert die NavigationsID des aktuellen gewählten Menüpunkts
+ *
* @return int
*/
public static function getActiveNavID()
@@ -153,6 +188,7 @@ class NavigationModel extends Database
/**
+ * Liefert den Seiten-Titel
* @return string
*/
public static function getTitle()
@@ -162,6 +198,7 @@ class NavigationModel extends Database
/**
+ * Liefert das Array für das KeyVisual
* @return array
*/
public static function getKeyVisual()
@@ -171,6 +208,7 @@ class NavigationModel extends Database
/**
+ * Liefert die Überschrift der Seite
* @return string
*/
public static function getHeadline()
@@ -180,6 +218,7 @@ class NavigationModel extends Database
/**
+ * Liefert die Seiteninhalte
* @return array
*/
public static function getContents()
@@ -189,10 +228,145 @@ class NavigationModel extends Database
/**
+ * Liefert die Navigationsdaten als flaches Array
* @return array
*/
public static function getData()
{
return self::$data;
}
+
+
+ /**
+ * Liefert die Navigationsdaten, sortiert nach ihrem Elternknoten
+ * @return array
+ */
+ public static function getStructuredIndex()
+ {
+ $tmpData = self::getIndex();
+ $structuredData = array();
+ foreach ($tmpData as $navID => $navData)
+ {
+ $structuredData['navStart_' . $navData['navStart']]['navID_' . $navID] = $navData;
+ }
+ return $structuredData;
+ }
+
+
+ /**
+ * Liefert einen Link, der innerhalb des NavStarts unique ist
+ * @author Christian Steinle
+ *
+ * @param int $navStart
+ * @param string $navName
+ * @return string
+ */
+ public static function getUniqueNavLink($navStart, $navName)
+ {
+ $commonReplacements = array('ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss', ' ' => '_', '"', '', '\'' => '');
+ $registry = Registry::getInstance();
+ $replacements = $registry->editorConfig['linkReplacements'];
+ $navLink = trim(str_replace($replacements, '', $navName));
+ $navLink = mb_convert_case($navLink, MB_CASE_LOWER);
+ $navLink = str_replace(array_keys($commonReplacements), array_values($commonReplacements), $navLink);
+
+ self::$filter = 'navStart = ' . $navStart;
+ $existingNavLinks = 0;
+ $tmpData = self::getIndex();
+
+ foreach ($tmpData as $navPoint)
+ {
+ if ($navPoint['navLink'] == $navLink)
+ {
+ ++$existingNavLinks;
+ }
+ }
+
+ if ($existingNavLinks === 0)
+ {
+ return $navLink;
+ }
+ return $navLink . '_' . $existingNavLinks;
+ }
+
+
+ /**
+ * Sortiert die Navigationspunkte eines übergebenen Elternelements
+ * @author Christian Steinle
+ *
+ * @param array $navPointData
+ * @return int
+ */
+ public static function updateSortAfterInsert(array $navPointData)
+ {
+ if (!isset($navPointData['navStart']) || $navPointData['navStart'] === '')
+ {
+ return -1;
+ }
+
+ self::$filter = 'navStart = ' . $navPointData['navStart'];
+ $sortOrder = $navPointData['navSort'];
+ $tmpData = self::getIndex();
+ unset($tmpData[$navPointData['navID']]);
+ if ($sortOrder != 0)
+ {
+ array_splice($tmpData, 0, $sortOrder);
+ }
+
+ foreach($tmpData as $navData)
+ {
+ ++$sortOrder;
+ self::update(array('navID' => $navData['navID'], 'navSort' => $sortOrder));
+ }
+
+ return 1;
+ }
+
+
+ /**
+ * Sortiert die Navigationspunkte eines Elternelements um
+ * @author Christian Steinle
+ *
+ * @param $sortData
+ * @return int
+ */
+ public static function updateSort($sortData)
+ {
+ foreach($sortData as $navSort => $navID)
+ {
+ self::update(array('navID' => $navID, 'navSort' => $navSort));
+ }
+
+ return 1;
+ }
+
+
+ /**
+ * Legt die Bilddaten des Keyvisuals an, und liefert den passenden JSON-String für den Eintrag in die Datenbank-Tabelle
+ * @author Christian Steinle
+ *
+ * @param array $request
+ */
+ protected static function beforeInsert(&$request)
+ {
+ $registry = Registry::getInstance();
+ $imageData = $registry->editorConfig['imageDimension']['keyVisual'];
+ $standardImagePath = substr(str_replace(PATH_PREFIX, '', PATH_ROOT), 0, -1) . $imageData['standardImage'];
+
+ $filename = end(explode('/', $standardImagePath));
+ $fileArray = ImageModel::filenameToArray($filename);
+ $imageData = array();
+ $imageData['imageOrigName'] = $fileArray['filename'];
+ $imageData['imageExtension'] = $fileArray['extension'];
+ $imageData['imageName'] = $fileArray['filename'];
+ $imageData['imageTitle'] = $fileArray['filename'];
+ list($width, $height) = getimagesize($standardImagePath);
+ $imageData['imageTop'] = 0;
+ $imageData['imageLeft'] = 0;
+ $imageData['imageHeight'] = $height;
+ $imageData['imageWidth'] = $width;
+
+ $imageID = ImageModel::insert($imageData);
+ $request['navKeyVisual'] = json_encode(array('Controller' => 'KeyVisual', 'Type' => 'Single', 'IDs' => array($imageID)));
+ }
}
\ No newline at end of file
diff --git a/rendering/Model/SublineModel.php b/rendering/Model/SublineModel.php
new file mode 100644
index 0000000..96dda99
--- /dev/null
+++ b/rendering/Model/SublineModel.php
@@ -0,0 +1,23 @@
+isEditable)
{
- $this->navigationHtml .= 'data['text']); ?>