commit d6a4fc4f76fe0977f3a7257c0e85c56b7d9e3916 Author: bmen Date: Sun Sep 22 16:53:30 2019 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..90ec22b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.svn diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..1b8ad74 --- /dev/null +++ b/.htaccess @@ -0,0 +1,23 @@ +Options FollowSymLinks + +RewriteEngine on +RewriteBase / + +# Weiterleitung zu Subdomains +# RewriteRule ^(demo)(.*)$ http://$1.2erlei.de$2 [L] + +# Federleicht-# Spezielle Weiterleitungsregeln +RewriteRule ^favicon.ico$ /public/img/favicon.ico [L] +RewriteRule ^robots.txt$ /public/robots.txt [L] + +# Federleicht-Verzeichnisse sperren +# Wenn diese Namen als Modul verwendet werden, +# hier loeschen und weiter unten eintragen. +RewriteRule ^(app|cache|config|fl|log|script|test|private)(.*)$ / [R=301] + +# Daten auf oeffentliches Verzeichnis umleiten +RewriteRule ^(css|img|js|php)(.*)$ /public/$1$2 [R] + +# installierte Module von Federleicht verarbeiten lassen. +RewriteRule ^(user|basecontent|about|coding|design|pages|portfolio)(.*)$ - [C] +RewriteRule ^(.*)$ index.php [L] diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..115ea6c --- /dev/null +++ b/INSTALL @@ -0,0 +1,45 @@ +Hinweise zur Einrichtung +======================== + + +DATENBANK + +Die Datei config/database.ini muss erzeugt werden. config/database.ini.sample +kann dafuer kopiert und angepasst werden. +Derzeit wird keine Datenbank verwendet. Daher ist in der config/database.ini +type=null einzutragen. + + +SCRIPTSPRACHEN + +Fuer den Betrieb der Webseite ist PHP erforderlich. Getestet wurde mit +Version 5.2. + + +WEBSERVER + +Das PHP-Framework nutzt URL-Rewriting. Daher sollte ein Apache-Webserver mit +mod_rewrite verwendet werden. + +In die Apachekonfiguration muss aufgenommen werden: + +# This Directory contains the upload.cgi-Script +# As it is accessible anyway, make it a cgi-dir... + + SetHandler cgi-script + Options +ExecCGI + + +Dies sollte im entsprechenden VirtualHost-Abschnitt stehen. + + +Kurzfassung der Anforderungen +============================= + +Apache 2 +Apache-Modul "mod_rewrite" + + +config/database.ini + +PHP 5.2 diff --git a/app/elements/admin_head.php b/app/elements/admin_head.php new file mode 100644 index 0000000..245b1d6 --- /dev/null +++ b/app/elements/admin_head.php @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/elements/bc_info.php b/app/elements/bc_info.php new file mode 100644 index 0000000..6009586 --- /dev/null +++ b/app/elements/bc_info.php @@ -0,0 +1,17 @@ + + +

Meldungen

+
 
+
+
 
+
 
+
+ +

Hilfe

+
 
+ get_help($vars['cap']['controller'], $vars['cap']['action']); ?> +
 
+

Handbuch

+
 
+
+ diff --git a/app/elements/bc_nav.php b/app/elements/bc_nav.php new file mode 100644 index 0000000..a2d4509 --- /dev/null +++ b/app/elements/bc_nav.php @@ -0,0 +1,6 @@ +

+ Startseite | + Webseite ansehen | + Benutzerverwaltung | + Papierkorb +

diff --git a/app/elements/google_analytics.php b/app/elements/google_analytics.php new file mode 100644 index 0000000..af214cb --- /dev/null +++ b/app/elements/google_analytics.php @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/app/elements/haftungsausschluss.php b/app/elements/haftungsausschluss.php new file mode 100644 index 0000000..7877971 --- /dev/null +++ b/app/elements/haftungsausschluss.php @@ -0,0 +1,9 @@ +

Haftungsausschluss:

+ +

Die 2erlei übernimmt keine Garantie dafür, dass die auf dieser Website +bereitgestellten Informationen vollständig, richtig und in jedem Fall aktuell +sind. Dies gilt auch für alle Verbindungen ("Links"), auf die diese Website +direkt oder indirekt verweist. 2erlei Berlin ist für den Inhalt einer Seite, +die mit einem solchen Link erreicht wird, nicht verantwortlich. 2erlei Berlin +behält sich das Recht vor, ohne vorherige Ankündigung Änderungen oder +Ergänzungen der bereitgestellten Informationen vorzunehmen.

diff --git a/app/elements/header.php b/app/elements/header.php new file mode 100644 index 0000000..c2aba8e --- /dev/null +++ b/app/elements/header.php @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/elements/kundennavi.php b/app/elements/kundennavi.php new file mode 100644 index 0000000..a35400c --- /dev/null +++ b/app/elements/kundennavi.php @@ -0,0 +1,11 @@ + +

Startseite

+Kunden-Login

+

Sitemap

+

Kontakt

+ --> + + */ ?> diff --git a/app/elements/lightbox.php b/app/elements/lightbox.php new file mode 100644 index 0000000..def4acd --- /dev/null +++ b/app/elements/lightbox.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/elements/navigation.php b/app/elements/navigation.php new file mode 100644 index 0000000..17e37d8 --- /dev/null +++ b/app/elements/navigation.php @@ -0,0 +1,14 @@ +

+Form & Farbe + | + Code & Technik + | + über 2erlei + | + */ ?> +   Referenzen + | + Kontakt +

+ diff --git a/app/elements/subnavigation_portfolio.php b/app/elements/subnavigation_portfolio.php new file mode 100644 index 0000000..d790f57 --- /dev/null +++ b/app/elements/subnavigation_portfolio.php @@ -0,0 +1,21 @@ + + + + diff --git a/app/elements/unten.php b/app/elements/unten.php new file mode 100644 index 0000000..694dd9a --- /dev/null +++ b/app/elements/unten.php @@ -0,0 +1,8 @@ +

+ 2005 - 2012   2erlei Konzeption & Gestaltung   + | + Kontakt + | + Impressum +

+ diff --git a/app/helper/bereiche.php b/app/helper/bereiche.php new file mode 100644 index 0000000..9783898 --- /dev/null +++ b/app/helper/bereiche.php @@ -0,0 +1,101 @@ + + * @version 0.2 + * @license All Rights Reserved + */ +class bereiche { + var $indent; + var $indent_str = ''; + + /** + * Konstruktor + * + * @param int $indent + */ + function bereiche($indent=3) { + $this->indent = (int) $indent; + if( $this->indent == 3 ) $this->indent_str = "\t\t\t"; + } + + /** + * Oberen Abschluss des Bereichs ausgeben + * + * @param string $id ID des Bereichs + * @param string $title Ãœberschrift des Bereichs + */ + function oben($id, $title) { + $html[] = '

'.$title.'

'; + $html[] = '
 
'; + $this->output($html); + } + + /** + * Trennstrich einfügen + */ + function unterbrechung() { + $html[] = '
 
'; + $html[] = '
 
'; + $this->output($html); + } + + /** + * Buttons ausgeben + * + * @param string $buttons Kommaseparierte Liste der einzufügenden Buttons + */ + function buttons($buttons='') { + $html[] = '
 
'; + + if ($buttons != '') { + needs('buttons'); + $the_buttons = new buttons(); + + $html[] = '

'; + + $buttons = explode(',', $buttons); + foreach( $buttons as $button ) { + @list($button_method, $button_param) = explode(':', $button); + + if ( method_exists($the_buttons, $button_method) ) { + $buttonhtml = $the_buttons->$button_method($button_param); + } else { + $buttonhtml = ''; + } + + $html[] = ' ' . $buttonhtml; + } + + $js = $the_buttons->get_js(); + if ( $js != '' ) { + $html[] = $js; + } + + $html[] = '

'; + } + $this->output($html); + } + + /** + * Unteren Abschluss des Bereichs ausgeben + */ + function unten() { + $html[] = '
 
'; + $html[] = '
'; + $this->output($html); + } + + /** + * Ausgabe des HTML + * + * @param array $html + */ + function output($html) { + foreach( $html as $line ) { + echo $this->indent_str . $line . PHP_EOL; + } + } +} +?> diff --git a/app/helper/buttons.php b/app/helper/buttons.php new file mode 100644 index 0000000..0e8674f --- /dev/null +++ b/app/helper/buttons.php @@ -0,0 +1,94 @@ + + * @version 0.1 + * @license All Rights Reserved + */ +class buttons { + var $javascript = ''; + + function buttons() { + } + + function get_js() { + if ( $this->javascript == '' ) return ''; + + $js = ''; + + $js .= ''; + + $this->javascript = ''; + return $js; + } + + function add_js($js) { + $this->javascript .= $js . PHP_EOL; + } + + function weiter($next) { + $html = 'weiter'; + $this->add_js("var field = $('weiter-".$next."'); field.href = \"javascript:Bereiche.toggle('" . $next . "');\";"); + return $html; + } + + function zurueck($prev) { + $html = 'zurück'; + $this->add_js("var field = $('zurueck-".$prev."'); field.href = \"javascript:Bereiche.toggle('" . $prev . "');\";"); + return $html; + } + + function speichern() { + $html = ''; + return $html; + } + + function zuordnen() { + $html = ''; + return $html; + } + + function abbrechen($target='/') { + $html = 'Abbrechen'; + $this->add_js("var field = $('abbrechen-button'); field.href = \"javascript:window.history.back();\";"); + return $html; + } + + function hinzufuegen($target='/') { + $html = 'hinzufügen'; + return $html; + } + + function loeschen($target='/') { + $html = 'löschen'; + return $html; + } + + function uebernehmen($target='/') { + $html = 'löschen'; + return $html; + } + + /** + * Reine JavaScript-Buttons hinzufügen + * + * @param string $params Die Parameter werden wie folgt erwartet: + * modulname-bereichid-jsname-buttons + * + * Die Buttons werden dabei wie folgt erwartet: + * button1/button2/button3 + */ + function js($params) { + list($modul, $bereich, $js_name, $buttons) = explode('-', $params); + $buttons = explode('/', $buttons); + $this->add_js($js_name . ' = new Buttons(\''.$modul.'\', \''.$bereich.'\');'); + $this->add_js($js_name . '.write(\''.$js_name.'\', [\''.implode('\',\'', $buttons).'\']);'); + } +} +?> diff --git a/app/helper/classes/doc.inc.php b/app/helper/classes/doc.inc.php new file mode 100644 index 0000000..95ebff7 --- /dev/null +++ b/app/helper/classes/doc.inc.php @@ -0,0 +1,861 @@ +]+)([^>]+)?>(.*?)<\s*\/\\1\s*>\s*([^<]+)?(.*)|\s*\s*|^\s*<\s*([^\s>]+)([^>]*)\/\s*>\s*([^<>]+)?|||]+)\s*(["\'])([^\14]+)\14\s*>|^([^<]+)(.*)/smi'); +*/ + +define("MINIXML_COMPLETE_REGEX",'/^\s*<\s*([^\s>]+)(\s+[^>]+)?>(.*?)<\s*\/\1\s*>\s*([^<]+)?(.*)|^\s*\s*(.*)|^\s*<\s*([^\s>]+)([^>]+)\/\s*>\s*(.*)|^\s*\s*(.*)|^\s*\s*(.*)|^\s*]+)\s*(["\'])([^\17]+)\17\s*>\s*(.*)|^([^<]+)(.*)/smi'); + +/* +#define("MINIXML_SIMPLE_REGEX", +# // 1 2 3 4 5 6 7 8 9 #10 11 +#'/\s*<\s*([^\s>]+)([^>]+)?>(.*?)<\s*\/\\1\s*>\s*([^<]+)?(.*)|\s*\s*|\s*<\s*([^\s>]+)([^>]*)\/\s*>\s*([^<>]+)?|^([^<]+)(.*)/smi'); + +*/ +define("MINIXML_SIMPLE_REGEX",'/^\s*<\s*([^\s>]+)(\s+[^>]+)?>(.*?)<\s*\/\1\s*>\s*([^<]+)?(.*)|^\s*\s*(.*)|^\s*<\s*([^\s>]+)([^>]+)\/\s*>\s*(.*)|^([^<]+)(.*)/smi'); + + +require_once(MINIXML_CLASSDIR . "/element.inc.php"); + +/*************************************************************************************************** +**************************************************************************************************** +***** +***** MiniXMLDoc +***** +**************************************************************************************************** +***************************************************************************************************/ + +/* MiniXMLDoc class +** +** The MiniXMLDoc class is the programmer's handle to MiniXML functionality. +** +** A MiniXMLDoc instance is created in every program that uses MiniXML. +** With the MiniXMLDoc object, you can access the root MiniXMLElement, +** find/fetch/create elements and read in or output XML strings. +**/ +class MiniXMLDoc { + var $xxmlDoc; + var $xuseSimpleRegex; + var $xRegexIndex; + + /* MiniXMLDoc [XMLSTRING] + ** Constructor, create and init a MiniXMLDoc object. + ** + ** If the optional XMLSTRING is passed, the document will be initialised with + ** a call to fromString using the XMLSTRING. + ** + */ + function MiniXMLDoc ($string=NULL) + { + /* Set up the root element - note that it's name get's translated to a + ** string. + */ + $this->xxmlDoc = new MiniXMLElement("PSYCHOGENIC_ROOT_ELEMENT"); + $this->xuseSimpleRegex = MINIXML_USE_SIMPLE; + if (! is_null($string)) + { + $this->fromString($string); + } + + } + + function init () + { + $this->xxmlDoc = new MiniXMLElement("PSYCHOGENIC_ROOT_ELEMENT"); + } + + /* getRoot + ** Returns a reference the this document's root element + ** (an instance of MiniXMLElement) + */ + function &getRoot () + { + return $this->xxmlDoc; + } + + + /* setRoot NEWROOT + ** Set the document root to the NEWROOT MiniXMLElement object. + **/ + function setRoot (&$root) + { + if ($this->isElement($root)) + { + $this->xxmlDoc = $root; + } else { + return _MiniXMLError("MiniXMLDoc::setRoot(): Trying to set non-MiniXMLElement as root"); + } + } + + /* isElement ELEMENT + ** Returns a true value if ELEMENT is an instance of MiniXMLElement, + ** false otherwise. + */ + function isElement (&$testme) + { + if (is_null($testme)) + { + return 0; + } + + return method_exists($testme, 'MiniXMLElement'); + } + + + /* isNode NODE + ** Returns a true value if NODE is an instance of MiniXMLNode, + ** false otherwise. + */ + function isNode (&$testme) + { + if (is_null($testme)) + { + return 0; + } + + return method_exists($testme, 'MiniXMLNode'); + } + + + /* createElement NAME [VALUE] + ** Creates a new MiniXMLElement with name NAME. + ** This element is an orphan (has no assigned parent) + ** and will be lost unless it is appended (MiniXMLElement::appendChild()) + ** to an element at some point. + ** + ** If the optional VALUE (string or numeric) parameter is passed, + ** the new element's text/numeric content will be set using VALUE. + ** + ** Returns a reference to the newly created element (use the =& operator) + */ + function &createElement ($name=NULL, $value=NULL) + { + $newElement = new MiniXMLElement($name); + + if (! is_null($value)) + { + if (is_numeric($value)) + { + $newElement->numeric($value); + } elseif (is_string($value)) + { + $newElement->text($value); + } + } + + return $newElement; + } + + /* getElement NAME + ** Searches the document for an element with name NAME. + ** + ** Returns a reference to the first MiniXMLElement with name NAME, + ** if found, NULL otherwise. + ** + ** NOTE: The search is performed like this, returning the first + ** element that matches: + ** + ** - Check the Root Element's immediate children (in order) for a match. + ** - Ask each immediate child (in order) to MiniXMLElement::getElement() + ** (each child will then proceed similarly, checking all it's immediate + ** children in order and then asking them to getElement()) + */ + function &getElement ($name) + { + + $element = $this->xxmlDoc->getElement($name); + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("MiniXMLDoc::getElement(): Returning element $element"); + } + + return $element; + + } + + + /* getElementByPath PATH + ** Attempts to return a reference to the (first) element at PATH + ** where PATH is the path in the structure from the root element to + ** the requested element. + ** + ** For example, in the document represented by: + ** + ** + ** + ** + ** + ** + ** + ** DA42 + ** + ** + ** D99983FFF + ** + ** + ** ss-839uent + ** + ** + ** + ** + ** $accessid =& $xmlDocument->getElementByPath('partRateRequest/vendor/accessid'); + ** + ** Will return what you expect (the accessid element with attributes user = "myusername" + ** and password = "mypassword"). + ** + ** BUT be careful: + ** $accessid =& $xmlDocument->getElementByPath('partRateRequest/partList/partNum'); + ** + ** will return the partNum element with the value "DA42". Other partNums are + ** inaccessible by getElementByPath() - Use MiniXMLElement::getAllChildren() instead. + ** + ** Returns the MiniXMLElement reference if found, NULL otherwise. + */ + function &getElementByPath ($path) + { + + $element = $this->xxmlDoc->getElementByPath($path); + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Returning element $element"); + } + + return $element; + + } + + function fromFile ($filename) + { + $modified = stat($filename); + if (! is_array($modified)) + { + _MiniXMLError("Can't stat '$filename'"); + return NULL; + } + + if (MINIXML_USEFROMFILECACHING > 0) + { + + $tmpName = MINIXML_FROMFILECACHEDIR . '/' . 'minixml-' . md5($filename); + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Trying to open cach file $tmpName (for '$filename')"); + } + $cacheFileStat = stat($tmpName); + + if (is_array($cacheFileStat) && $cacheFileStat[9] > $modified[9]) + { + + $fp = @fopen($tmpName,"r"); + if ($fp) + { + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Reading file '$filename' from object cache instead ($tmpName)"); + } + $tmpFileSize = filesize($tmpName); + $tmpFileContents = fread($fp, $tmpFileSize); + + $serializedObj = unserialize($tmpFileContents); + + $sRoot =& $serializedObj->getRoot(); + if ($sRoot) + { + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Restoring object from cache file $tmpName"); + } + $this->setRoot($sRoot); + + /* Return immediately, such that we don't refresh the cache */ + return $this->xxmlDoc->numChildren(); + + } /* end if we got a root element from unserialized object */ + + } /* end if we sucessfully opened the file */ + + + } /* end if cache file exists and is more recent */ + } + + + ob_start(); + readfile($filename); + $filecontents = ob_get_contents(); + ob_end_clean(); + + $retVal = $this->fromString($filecontents); + + if (MINIXML_USEFROMFILECACHING > 0) + { + $this->saveToCache($filename); + } + + return $retVal; + + + } + + function saveToCache ($filename) + { + $tmpName = MINIXML_FROMFILECACHEDIR . '/' . 'minixml-' . md5($filename); + + $fp = @fopen($tmpName, "w"); + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Saving object to cache as '$tmpName'"); + } + + if ($fp) + { + + $serialized = serialize($this); + fwrite($fp, $serialized); + + fclose($fp); + } else { + _MiniXMLError("Could not open $tmpName for write in MiniXMLDoc::saveToCache()"); + } + + } + + /* fromString XMLSTRING + ** + ** Initialise the MiniXMLDoc (and it's root MiniXMLElement) using the + ** XML string XMLSTRING. + ** + ** Returns the number of immediate children the root MiniXMLElement now + ** has. + */ + function fromString (&$XMLString) + { + $useSimpleFlag = $this->xuseSimpleRegex; + + + if ($this->xuseSimpleRegex || ! preg_match('/xuseSimpleRegex = 1; + + $this->xRegexIndex = array( + 'biname' => 1, + 'biattr' => 2, + 'biencl' => 3, + 'biendtxt' => 4, + 'birest' => 5, + 'comment' => 6, + 'uname' => 8, + 'uattr' => 9, + 'plaintxt' => 11, + 'plainrest' => 12 + ); + $regex = MINIXML_SIMPLE_REGEX; + + } else { + + $this->xRegexIndex = array( + 'biname' => 1, + 'biattr' => 2, + 'biencl' => 3, + 'biendtxt' => 4, + 'birest' => 5, + 'comment' => 6, + 'uname' => 8, + 'uattr' => 9, + 'cdata' => 11, + 'doctypedef' => 13, + 'doctypecont' => 14, + 'entityname' => 16, + 'entitydef' => 18, + 'plaintxt' => 20, + 'plainrest' => 21 + ); + $regex = MINIXML_COMPLETE_REGEX; + } + + $this->fromSubString($this->xxmlDoc, $XMLString, $regex); + + $this->xuseSimpleRegex = $useSimpleFlag; + + return $this->xxmlDoc->numChildren(); + + } + + + function fromArray (&$init, $params=NULL) + { + + $this->init(); + + + if (! is_array($init) ) + { + + return _MiniXMLError("MiniXMLDoc::fromArray(): Must Pass an ARRAY to initialize from"); + } + + if (! is_array($params) ) + { + $params = array(); + } + + if ( $params["attributes"] && is_array($params["attributes"]) ) + { + + $attribs = array(); + foreach ($params["attributes"] as $attribName => $value) + { + if (! (array_key_exists($attribName, $attribs) && is_array($attribs[$attribName]) ) ) + { + $attribs[$attribName] = array(); + } + + if (is_array($value)) + { + foreach ($value as $v) + { + if (array_key_exists($v, $attribs[$attribName])) + { + $attribs[$attribName][$v]++; + } else { + $attribs[$attribName][$v] = 1; + } + } + } else { + if (array_key_exists($value,$attribs[$attribName])) + { + $attribs[$attribName][$value]++; + } else { + $attribs[$attribName][$value] = 1; + } + } + } + + // completely replace old attributes by our optimized array + $params["attributes"] = $attribs; + } else { + $params["attributes"] = array(); + } + + foreach ($init as $keyname => $value) + { + $sub = $this->_fromArray_getExtractSub($value); + + + $this->$sub($keyname, $value, $this->xxmlDoc, $params); + + } + + + return $this->xxmlDoc->numChildren(); + + } + + function _fromArray_getExtractSub ($v) + { + // is it a string, a numerical array or an associative array? + $sub = "_fromArray_extract"; + if (is_array($v)) + { + if (_MiniXML_NumKeyArray($v)) + { + // All numeric - assume it is a "straight" array + $sub .= "ARRAY"; + } else { + $sub .= "AssociativeARRAY"; + } + + } else { + $sub .= "STRING"; + } + + + return $sub; + } + + + + + + function _fromArray_extractAssociativeARRAY ($name, &$value, &$parent, &$params) + { + + $thisElement =& $parent->createChild($name); + + foreach ($value as $key => $val) + { + + $sub = $this->_fromArray_getExtractSub($val); + + + $this->$sub($key, $val, $thisElement, $params); + + } + + return; + } + + function _fromArray_extractARRAY ($name, &$value, &$parent, &$params) + { + + foreach ($value as $val) + { + $sub = $this->_fromArray_getExtractSub($val); + + + $this->$sub($name, $val, $parent, $params); + + } + + return; + } + + + function _fromArray_extractSTRING ($name, $value="", &$parent, &$params) + { + + $pname = $parent->name(); + + if ( + ( array_key_exists($pname, $params['attributes']) && is_array($params['attributes'][$pname]) + && array_key_exists($name, $params['attributes'][$pname]) && $params['attributes'][$pname][$name]) + || ( + array_key_exists('-all', $params['attributes']) && is_array($params['attributes']['-all']) + && array_key_exists($name, $params['attributes']['-all']) && $params['attributes']['-all'][$name]) + ) + { + $parent->attribute($name, $value); + } elseif ($name == '-content') { + + $parent->text($value); + } else { + $parent->createChild($name, $value); + } + + return; + } + + + + function time ($msg) + { + error_log("\nMiniXML msg '$msg', time: ". time() . "\n"); + } + // fromSubString PARENTMINIXMLELEMENT XMLSUBSTRING + // private method, called recursively to parse the XMLString in little sub-chunks. + function fromSubString (&$parentElement, &$XMLString, &$regex) + { + //$this->time('fromSubStr'); + + if (is_null($parentElement) || empty($XMLString) || preg_match('/^\s*$/', $XMLString)) + { + return; + } + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Called fromSubString() with parent '" . $parentElement->name() . "'\n"); + } + + $matches = array(); + if (preg_match_all( $regex, $XMLString, $matches)) + { + // $this->time('a match'); + + $mcp = $matches; + + $numMatches = count($mcp[0]); + + for($i=0; $i < $numMatches; $i++) + { + if (MINIXML_DEBUG > 1) + { + _MiniXMLLog ("Got $numMatches CHECKING: ". $mcp[0][$i] . "\n"); + } + + $uname = $mcp[$this->xRegexIndex['uname']][$i]; + $comment = $mcp[$this->xRegexIndex['comment']][$i]; + if ($this->xuseSimpleRegex) + { + $cdata = NULL; + $doctypecont = NULL; + $entityname = NULL; + + $tailEndIndexes = array(5, 7, 10, 12); + } else { + + $cdata = $mcp[$this->xRegexIndex['cdata']][$i]; + $doctypecont = $mcp[$this->xRegexIndex['doctypecont']][$i]; + $entityname = $mcp[$this->xRegexIndex['entityname']][$i]; + + $tailEndIndexes = array(5, 7, 10, 12, 15, 19, 21); + } + + $plaintext = $mcp[$this->xRegexIndex['plaintxt']][$i]; + + // check all the 'tailend' (i.e. rest of string) matches for more content + $moreContent = ''; + $idx = 0; + while (empty($moreContent) && ($idx < count($tailEndIndexes))) + { + if (! empty($mcp[$tailEndIndexes[$idx]][$i])) + { + $moreContent = $mcp[$tailEndIndexes[$idx]][$i]; + } + + $idx++; + } + + + + if ($uname) + { + // _MiniXMLLog ("Got UNARY $uname"); + $newElement =& $parentElement->createChild($uname); + $this->_extractAttributesFromString($newElement, $mcp[$this->xRegexIndex['uattr']][$i]); + + } elseif ($comment) { + //_MiniXMLLog ("Got comment $comment"); + $parentElement->comment($comment); + + } elseif ($cdata) { + //_MiniXMLLog ("Got cdata $cdata"); + $newElement = new MiniXMLElementCData($cdata); + $parentElement->appendChild($newElement); + } elseif ($doctypecont) { + //_MiniXMLLog ("Got doctype $doctypedef '" . $mcp[11][$i] . "'"); + $newElement = new MiniXMLElementDocType($mcp[$this->xRegexIndex['doctypedef']][$i]); + $appendedChild =& $parentElement->appendChild($newElement); + $this->fromSubString($appendedChild, $doctypecont, $regex); + + } elseif ($entityname ) { + //_MiniXMLLog ("Got entity $entityname"); + $newElement = new MiniXMLElementEntity ($entityname, $mcp[$this->xRegexIndex['entitydef']][$i]); + $parentElement->appendChild($newElement); + + } elseif ($plaintext) { + + if (! preg_match('/^\s+$/', $plaintext)) + { + $parentElement->createNode($plaintext); + } + + } elseif($mcp[$this->xRegexIndex['biname']]) { + + // _MiniXMLLog("Got BIN NAME: " . $mcp[$this->xRegexIndex['biname']][$i]); + + $nencl = $mcp[$this->xRegexIndex['biencl']][$i]; + $finaltxt = $mcp[$this->xRegexIndex['biendtxt']][$i]; + + $newElement =& $parentElement->createChild($mcp[$this->xRegexIndex['biname']][$i]); + $this->_extractAttributesFromString($newElement, $mcp[$this->xRegexIndex['biattr']][$i]); + + + + $plaintxtMatches = array(); + if (preg_match("/^\s*([^\s<][^<]*)/", $nencl, $plaintxtMatches)) + { + $txt = $plaintxtMatches[1]; + $newElement->createNode($txt); + + $nencl = preg_replace("/^\s*([^<]+)/", "", $nencl); + } + + + if ($nencl && !preg_match('/^\s*$/', $nencl)) + { + $this->fromSubString($newElement, $nencl, $regex); + } + + if ($finaltxt) + { + $parentElement->createNode($finaltxt); + } + + + } /* end switch over type of match */ + + if (! empty($moreContent)) + { + $this->fromSubString($parentElement, $moreContent, $regex); + } + + + } /* end loop over all matches */ + + + } /* end if there was a match */ + + } /* end method fromSubString */ + + + /* toString [DEPTH] + ** Converts this MiniXMLDoc object to a string and returns it. + ** + ** The optional DEPTH may be passed to set the space offset for the + ** first element. + ** + ** If the optional DEPTH is set to MINIXML_NOWHITESPACES. + ** When it is, no \n or whitespaces will be inserted in the xml string + ** (ie it will all be on a single line with no spaces between the tags. + ** + ** Returns a string of XML representing the document. + */ + function toString ($depth=0) + { + $retString = $this->xxmlDoc->toString($depth); + + if ($depth == MINIXML_NOWHITESPACES) + { + $xmlhead = ""; + } else { + $xmlhead = "\n "; + } + $search = array("/]*)>\s*/smi", + "/<\/PSYCHOGENIC_ROOT_ELEMENT>/smi"); + $replace = array($xmlhead, + ""); + $retString = preg_replace($search, $replace, $retString); + + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("MiniXML::toString() Returning XML:\n$retString\n\n"); + } + + + return $retString; + } + + + /* toArray + ** + ** Transforms the XML structure currently represented by the MiniXML Document object + ** into an array. + ** + ** More docs to come - for the moment, use var_dump($miniXMLDoc->toArray()) to see + ** what's going on :) + */ + + function & toArray () + { + + $retVal = $this->xxmlDoc->toStructure(); + + if (is_array($retVal)) + { + return $retVal; + } + + $retArray = array( + '-content' => $retVal, + ); + + return $retArray; + } + + + + + /* getValue() + ** Utility function, call the root MiniXMLElement's getValue() + */ + function getValue () + { + return $this->xxmlDoc->getValue(); + } + + + + /* dump + ** Debugging aid, dump returns a nicely formatted dump of the current structure of the + ** MiniXMLDoc object. + */ + function dump () + { + return serialize($this); + } + + + + // _extractAttributesFromString + // private method for extracting and setting the attributs from a + // ' a="b" c = "d"' string + function _extractAttributesFromString (&$element, &$attrString) + { + + if (! $attrString) + { + return NULL; + } + + $count = 0; + $attribs = array(); + // Set the attribs + preg_match_all('/([^\s]+)\s*=\s*([\'"])([^\2]*?)\2/sm', $attrString, $attribs); + + + for ($i = 0; $i < count($attribs[0]); $i++) + { + $attrname = $attribs[1][$i]; + $attrval = $attribs[3][$i]; + + if ($attrname) + { + $element->attribute($attrname, $attrval, ''); + $count++; + } + } + + return $count; + } + + /* Destructor to keep things clean -- patch by Ilya */ + function __destruct() + { + $this->xxmlDoc = null; + } + + +} + + + +/*************************************************************************************************** +**************************************************************************************************** +***** +***** MiniXML +***** +**************************************************************************************************** +***************************************************************************************************/ + +/* class MiniXML (MiniXMLDoc) +** +** Avoid using me - I involve needless overhead. +** +** Utility class - this is just an name aliase for the +** MiniXMLDoc class as I keep repeating the mistake of +** trying to create +** +** $xml = new MiniXML(); +** +*/ +class MiniXML extends MiniXMLDoc { + + function MiniXML () + { + $this->MiniXMLDoc(); + } +} + + + +?> \ No newline at end of file diff --git a/app/helper/classes/element.inc.php b/app/helper/classes/element.inc.php new file mode 100644 index 0000000..f7bd52c --- /dev/null +++ b/app/helper/classes/element.inc.php @@ -0,0 +1,1729 @@ + 0) +**/ + +class MiniXMLElement extends MiniXMLTreeComponent { + + + var $xname; + var $xattributes; + var $xchildren; + var $xnumChildren; + var $xnumElementChildren; + + var $xavoidLoops = MINIXML_AVOIDLOOPS; + + + /* MiniXMLElement NAME + ** Creates and inits a new MiniXMLElement + */ + function MiniXMLElement ($name=NULL) + { + $this->MiniXMLTreeComponent(); + $this->xname = NULL; + $this->xattributes = array(); + $this->xchildren = array(); + $this->xnumChildren = 0; + $this->xnumElementChildren = 0; + if ($name) + { + $this->name($name); + } else { + return _MiniXMLError("MiniXMLElement Constructor: must pass a name to constructor"); + } + } /* end method MiniXMLElement */ + + + /**************** Get/set methods for MiniXMLElement data *****************/ + + + /* name [NEWNAME] + ** + ** If a NEWNAME string is passed, the MiniXMLElement's name is set + ** to NEWNAME. + ** + ** Returns the element's name. + */ + function name ($setTo=NULL) + { + if (! is_null($setTo)) + { + if (! is_string($setTo)) + { + return _MiniXMLError("MiniXMLElement::name() Must pass a STRING to method to set name"); + } + + $this->xname = $setTo; + } + + return $this->xname; + + } /* end method name */ + + + + /* attribute NAME [SETTO [SETTOALT]] + ** + ** The attribute() method is used to get and set the + ** MiniXMLElement's attributes (ie the name/value pairs contained + ** within the tag, ) + ** + ** If SETTO is passed, the attribute's value is set to SETTO. + ** + ** If the optional SETTOALT is passed and SETTO is false, the + ** attribute's value is set to SETTOALT. This is usefull in cases + ** when you wish to set the attribute to a default value if no SETTO is + ** present, eg $myelement->attribute('href', $theHref, 'http://psychogenic.com') + ** will default to 'http://psychogenic.com'. + ** + ** Note: if the MINIXML_LOWERCASEATTRIBUTES define is > 0, all attribute names + ** will be lowercased (while setting and during retrieval) + ** + ** Returns the value associated with attribute NAME. + ** + */ + function attribute ($name, $primValue=NULL, $altValue=NULL) + { + $value = (is_null($primValue) ? $altValue : $primValue ); + + + if (MINIXML_UPPERCASEATTRIBUTES > 0) + { + $name = strtoupper($name); + } elseif (MINIXML_LOWERCASEATTRIBUTES > 0) + { + $name = strtolower($name); + } + + if (! is_null($value)) + { + + $this->xattributes[$name] = $value; + } + + if (! is_null($this->xattributes[$name])) + { + return $this->xattributes[$name]; + } else { + return NULL; + } + + } /* end method attribute */ + + + /* text [SETTO [SETTOALT]] + ** + ** The text() method is used to get or append text data to this + ** element (it is appended to the child list as a new MiniXMLNode object). + ** + ** If SETTO is passed, a new node is created, filled with SETTO + ** and appended to the list of this element's children. + ** + ** If the optional SETTOALT is passed and SETTO is false, the + ** new node's value is set to SETTOALT. See the attribute() method + ** for an example use. + ** + ** Returns a string composed of all child MiniXMLNodes' contents. + ** + ** Note: all the children MiniXMLNodes' contents - including numeric + ** nodes are included in the return string. + */ + function text ($setToPrimary = NULL, $setToAlternate=NULL) + { + $setTo = ($setToPrimary ? $setToPrimary : $setToAlternate); + + if (! is_null($setTo)) + { + $this->createNode($setTo); + } + + $retString = ''; + + /* Extract text from all child nodes */ + for($i=0; $i< $this->xnumChildren; $i++) + { + if ($this->isNode($this->xchildren[$i])) + { + $nodeTxt = $this->xchildren[$i]->getValue(); + if (! is_null($nodeTxt)) + { + $retString .= "$nodeTxt "; + + } /* end if text returned */ + + } /* end if this is a MiniXMLNode */ + + } /* end loop over all children */ + + return $retString; + + } /* end method text */ + + + + /* numeric [SETTO [SETTOALT]] + ** + ** The numeric() method is used to get or append numeric data to + ** this element (it is appended to the child list as a MiniXMLNode object). + ** + ** If SETTO is passed, a new node is created, filled with SETTO + ** and appended to the list of this element's children. + ** + ** If the optional SETTOALT is passed and SETTO is false, the + ** new node's value is set to SETTOALT. See the attribute() method + ** for an example use. + ** + ** Returns a space seperated string composed all child MiniXMLNodes' + ** numeric contents. + ** + ** Note: ONLY numerical contents are included from the list of child MiniXMLNodes. + ** + */ + function numeric ($setToPrimary = NULL, $setToAlternate=NULL) + { + $setTo = (is_null($setToPrimary) ? $setToAlternate : $setToPrimary); + + if (! is_null($setTo)) + { + $this->createNode($setTo); + } + + } /* end method numeric */ + + + /* comment CONTENTS + ** + ** The comment() method allows you to add a new MiniXMLElementComment to this + ** element's list of children. + ** + ** Comments will return a string when the element's toString() + ** method is called. + ** + ** Returns a reference to the newly appended MiniXMLElementComment + ** + */ + function & comment ($contents) + { + $newEl = new MiniXMLElementComment(); + + $appendedComment =& $this->appendChild($newEl); + $appendedComment->text($contents); + + return $appendedComment; + + } /* end method comment */ + + + + + + + + /* + ** docType DEFINITION + ** + ** Append a new element as a child of this + ** element. + ** + ** Returns the appended DOCTYPE element. You will normally use the returned + ** element to add ENTITY elements, like + + ** $newDocType =& $xmlRoot->docType('spec SYSTEM "spec.dtd"'); + ** $newDocType->entity('doc.audience', 'public review and discussion'); + */ + + function & docType ($definition) + { + + $newElement = new MiniXMLElementDocType($definition); + $appendedElement =& $this->appendChild($newElement); + + return $appendedElement; + } + /* + ** entity NAME VALUE + ** + ** Append a new element as a child of this + ** element. + + ** Returns the appended ENTITY element. + */ + function & entity ($name,$value) + { + + $newElement = new MiniXMLElementEntity($name, $value); + $appendedEl =& $this->appendChild($newElement); + + return $appendedEl; + } + + + /* + ** cdata CONTENTS + ** + ** Append a new element as a child of this element. + ** Returns the appended CDATA element. + ** + */ + + function & cdata ($contents) + { + $newElement = new MiniXMLElementCData($contents); + $appendedChild =& $this->appendChild($newElement); + + return $appendedChild; + } + + + /* getValue + ** + ** Returns a string containing the value of all the element's + ** child MiniXMLNodes (and all the MiniXMLNodes contained within + ** it's child MiniXMLElements, recursively). + ** + ** Note: the seperator parameter remains officially undocumented + ** since I'm not sure it will remain part of the API + */ + function getValue ($seperator=' ') + { + $retStr = ''; + $valArray = array(); + for($i=0; $i < $this->xnumChildren; $i++) + { + $value = $this->xchildren[$i]->getValue(); + if (! is_null($value)) + { + array_push($valArray, $value); + } + } + if (count($valArray)) + { + $retStr = implode($seperator, $valArray); + } + return $retStr; + + } /* end method getValue */ + + + + /* getElement NAME + ** Searches the element and it's children for an element with name NAME. + ** + ** Returns a reference to the first MiniXMLElement with name NAME, + ** if found, NULL otherwise. + ** + ** NOTE: The search is performed like this, returning the first + ** element that matches: + ** + ** - Check this element for a match + ** - Check this element's immediate children (in order) for a match. + ** - Ask each immediate child (in order) to MiniXMLElement::getElement() + ** (each child will then proceed similarly, checking all it's immediate + ** children in order and then asking them to getElement()) + */ + function &getElement ($name) + { + + if (MINIXML_DEBUG > 0) + { + $elname = $this->name(); + _MiniXMLLog("MiniXMLElement::getElement() called for $name on $elname."); + } + if (is_null($name)) + { + return _MiniXMLError("MiniXMLElement::getElement() Must Pass Element name."); + } + + + /** Must only check children as checking $this results in an inability to + *** fetch nested objects with the same name + *** + *** + *** + *** Can't get here from tag or from the first 'nested' + *** + *** + *** + if (MINIXML_CASESENSITIVE > 0) + { + if (strcmp($this->xname, $name) == 0) + { + /* This element is it * / + return $this; + } + } else { + + if (strcasecmp($this->xname,$name) == 0) + { + return $this; + } + } + + ***** end commented out section **** + */ + + if (! $this->xnumChildren ) + { + /* Not match here and and no kids - not found... */ + return NULL; + } + + /* Try each child (immediate children take priority) */ + for ($i = 0; $i < $this->xnumChildren; $i++) + { + $childname = $this->xchildren[$i]->name(); + if ($childname) + { + if (MINIXML_CASESENSITIVE > 0) + { + /* case sensitive matches only */ + if (strcmp($name, $childname) == 0) + { + return $this->xchildren[$i]; + } + } else { + /* case INsensitive matching */ + if (strcasecmp($name, $childname) == 0) + { + return $this->xchildren[$i]; + } + } /* end if case sensitive */ + } /* end if child has a name */ + + } /* end loop over all my children */ + + /* Use beautiful recursion, daniel san */ + for ($i = 0; $i < $this->xnumChildren; $i++) + { + $theelement =& $this->xchildren[$i]->getElement($name); + if ($theelement) + { + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("MiniXMLElement::getElement() returning element $theelement"); + } + return $theelement; + } + } + + /* Not found */ + return NULL; + + + } /* end method getElement */ + + + /* getElementByPath PATH + ** Attempts to return a reference to the (first) element at PATH + ** where PATH is the path in the structure (relative to this element) to + ** the requested element. + ** + ** For example, in the document represented by: + ** + ** + ** + ** + ** + ** + ** + ** DA42 + ** + ** + ** D99983FFF + ** + ** + ** ss-839uent + ** + ** + ** + ** + ** $partRate =& $xmlDocument->getElement('partRateRequest'); + ** + ** $accessid =& $partRate->getElementByPath('vendor/accessid'); + ** + ** Will return what you expect (the accessid element with attributes user = "myusername" + ** and password = "mypassword"). + ** + ** BUT be careful: + ** $accessid =& $partRate->getElementByPath('partList/partNum'); + ** + ** will return the partNum element with the value "DA42". Other partNums are + ** inaccessible by getElementByPath() - Use MiniXMLElement::getAllChildren() instead. + ** + ** Returns the MiniXMLElement reference if found, NULL otherwise. + */ + function &getElementByPath($path) + { + $names = split ("/", $path); + + $element = $this; + foreach ($names as $elementName) + { + if ($element && $elementName) /* Make sure we didn't hit a dead end and that we have a name*/ + { + /* Ask this element to get the next child in path */ + $element =& $element->getElement($elementName); + } + } + + return $element; + + } /* end method getElementByPath */ + + + + /* numChildren [NAMED] + ** + ** Returns the number of immediate children for this element + ** + ** If the optional NAMED parameter is passed, returns only the + ** number of immediate children named NAMED. + */ + function numChildren ($named=NULL) + { + if (is_null($named)) + { + return $this->xnumElementChildren; + } + + /* We require only children named '$named' */ + $allkids =& $this->getAllChildren($named); + + return count($allkids); + + + } + + + /* getAllChildren [NAME] + ** + ** Returns a reference to an array of all this element's MiniXMLElement children + ** + ** Note: although the MiniXMLElement may contain MiniXMLNodes as children, these are + ** not part of the returned list. + **/ + function &getAllChildren ($name=NULL) + { + $retArray = array(); + $count = 0; + + if (is_null($name)) + { + /* Return all element children */ + for($i=0; $i < $this->xnumChildren; $i++) + { + if (method_exists($this->xchildren[$i], 'MiniXMLElement')) + { + $retArray[$count++] =& $this->xchildren[$i]; + } + } + } else { + /* Return only element children with name $name */ + + for($i=0; $i < $this->xnumChildren; $i++) + { + if (method_exists($this->xchildren[$i], 'MiniXMLElement')) + { + if (MINIXML_CASESENSITIVE > 0) + { + if ($this->xchildren[$i]->name() == $name) + { + $retArray[$count++] =& $this->xchildren[$i]; + } + } else { + if (strcasecmp($this->xchildren[$i]->name(), $name) == 0) + { + $retArray[$count++] =& $this->xchildren[$i]; + } + } /* end if case sensitive */ + + } /* end if child is a MiniXMLElement object */ + + } /* end loop over all children */ + + } /* end if specific name was requested */ + + return $retArray; + + } /* end method getAllChildren */ + + + + function &insertChild (&$child, $idx=0) + { + + + + if (! $this->_validateChild($child)) + { + return; + } + + /* Set the parent for the child element to this element if + ** avoidLoops or MINIXML_AUTOSETPARENT is set + */ + if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) ) + { + if ($this->xparent == $child) + { + + $cname = $child->name(); + return _MiniXMLError("MiniXMLElement::insertChild() Tryng to append parent $cname as child of " + . $this->xname ); + } + $child->parent($this); + } + + + $nextIdx = $this->xnumChildren; + $lastIdx = $nextIdx - 1; + if ($idx > $lastIdx) + { + + if ($idx > $nextIdx) + { + $idx = $lastIdx + 1; + } + $this->xchildren[$idx] = $child; + $this->xnumChildren++; + if ($this->isElement($child)) + { + $this->xnumElementChildren++; + } + + } elseif ($idx >= 0) + { + + $removed = array_splice($this->xchildren, $idx); + array_push($this->xchildren, $child); + $numRemoved = count($removed); + + for($i=0; $i<$numRemoved; $i++) + { + + array_push($this->xchildren, $removed[$i]); + } + $this->xnumChildren++; + if ($this->isElement($child)) + { + $this->xnumElementChildren++; + } + + + } else { + $revIdx = (-1 * $idx) % $this->xnumChildren; + $newIdx = $this->xnumChildren - $revIdx; + + if ($newIdx < 0) + { + return _MiniXMLError("Element::insertChild() Ended up with a negative index? ($newIdx)"); + } + + return $this->insertChild($child, $newIdx); + } + + return $child; + } + + + /* appendChild CHILDELEMENT + ** + ** appendChild is used to append an existing MiniXMLElement object to + ** this element's list. + ** + ** Returns a reference to the appended child element. + ** + ** NOTE: Be careful not to create loops in the hierarchy, eg + ** $parent->appendChild($child); + ** $child->appendChild($subChild); + ** $subChild->appendChild($parent); + ** + ** If you want to be sure to avoid loops, set the MINIXML_AVOIDLOOPS define + ** to 1 or use the avoidLoops() method (will apply to all children added with createChild()) + */ + function &appendChild (&$child) + { + + if (! $this->_validateChild($child)) + { + _MiniXMLLog("MiniXMLElement::appendChild() Could not validate child, aborting append"); + return NULL; + } + + /* Set the parent for the child element to this element if + ** avoidLoops or MINIXML_AUTOSETPARENT is set + */ + if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) ) + { + if ($this->xparent == $child) + { + + $cname = $child->name(); + return _MiniXMLError("MiniXMLElement::appendChild() Tryng to append parent $cname as child of " + . $this->xname ); + } + $child->parent($this); + } + + + $this->xnumElementChildren++; /* Note that we're addind a MiniXMLElement child */ + + /* Add the child to the list */ + $idx = $this->xnumChildren++; + $this->xchildren[$idx] =& $child; + + return $this->xchildren[$idx]; + + } /* end method appendChild */ + + + /* prependChild CHILDELEMENT + ** + ** prependChild is used to prepend an existing MiniXMLElement object to + ** this element's list. The child will be positioned at the begining of + ** the elements child list, thus it will be output first in the resulting XML. + ** + ** Returns a reference to the prepended child element. + */ + function &prependChild ($child) + { + + + if (! $this->_validateChild($child)) + { + _MiniXMLLog("MiniXMLElement::prependChild - Could not validate child, aborting."); + return NULL; + } + + /* Set the parent for the child element to this element if + ** avoidLoops or MINIXML_AUTOSETPARENT is set + */ + if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) ) + { + if ($this->xparent == $child) + { + + $cname = $child->name(); + return _MiniXMLError("MiniXMLElement::prependChild() Tryng to append parent $cname as child of " + . $this->xname ); + } + $child->parent($this); + } + + + $this->xnumElementChildren++; /* Note that we're adding a MiniXMLElement child */ + + /* Add the child to the list */ + $idx = $this->xnumChildren++; + array_unshift($this->xchildren, $child); + return $this->xchildren[0]; + + } /* end method prependChild */ + + function _validateChild (&$child) + { + + if (is_null($child)) + { + return _MiniXMLError("MiniXMLElement::_validateChild() need to pass a non-NULL MiniXMLElement child."); + } + + if (! method_exists($child, 'MiniXMLElement')) + { + return _MiniXMLError("MiniXMLElement::_validateChild() must pass a MiniXMLElement object to _validateChild."); + } + + /* Make sure element is named */ + $cname = $child->name(); + if (is_null($cname)) + { + _MiniXMLLog("MiniXMLElement::_validateChild() children must be named"); + return 0; + } + + + /* Check for loops */ + if ($child == $this) + { + _MiniXMLLog("MiniXMLElement::_validateChild() Trying to append self as own child!"); + return 0; + } elseif ( $this->xavoidLoops && $child->parent()) + { + _MiniXMLLog("MiniXMLElement::_validateChild() Trying to append a child ($cname) that already has a parent set " + . "while avoidLoops is on - aborting"); + return 0; + } + + return 1; + } + /* createChild ELEMENTNAME [VALUE] + ** + ** Creates a new MiniXMLElement instance and appends it to the list + ** of this element's children. + ** The new child element's name is set to ELEMENTNAME. + ** + ** If the optional VALUE (string or numeric) parameter is passed, + ** the new element's text/numeric content will be set using VALUE. + ** + ** Returns a reference to the new child element + ** + ** Note: don't forget to use the =& (reference assignment) operator + ** when calling createChild: + ** + ** $newChild =& $myElement->createChild('newChildName'); + ** + */ + function & createChild ($name, $value=NULL) + { + if (! $name) + { + return _MiniXMLError("MiniXMLElement::createChild() Must pass a NAME to createChild."); + } + + if (! is_string($name)) + { + return _MiniXMLError("MiniXMLElement::createChild() Name of child must be a STRING"); + } + + $child = new MiniXMLElement($name); + + $appendedChild =& $this->appendChild($child); + + if (! $appendedChild ) + { + _MiniXMLLog("MiniXMLElement::createChild() '$name' child NOT appended."); + return NULL; + } + + if (! is_null($value)) + { + if (is_numeric($value)) + { + $appendedChild->numeric($value); + } elseif (is_string($value)) + { + $appendedChild->text($value); + } + } + + $appendedChild->avoidLoops($this->xavoidLoops); + + return $appendedChild; + + } /* end method createChild */ + + + + /* removeChild CHILD + ** Removes CHILD from this element's list of children. + ** + ** Returns the removed child, if found, NULL otherwise. + */ + + function &removeChild (&$child) + { + if (! $this->xnumChildren) + { + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Element::removeChild() called for element without any children.") ; + } + return NULL; + } + + $foundChild = NULL; + $idx = 0; + while ($idx < $this->xnumChildren && ! $foundChild) + { + if ($this->xchildren[$idx] == $child) + { + $foundChild =& $this->xchildren[$idx]; + } else { + $idx++; + } + } + + if (! $foundChild) + { + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Element::removeChild() No matching child found.") ; + } + return NULL; + } + + array_splice($this->xchildren, $idx, 1); + + $this->xnumChildren--; + if ($this->isElement($foundChild)) + { + $this->xnumElementChildren--; + } + + unset ($foundChild->xparent) ; + return $foundChild; + } + + + /* removeAllChildren + ** Removes all children of this element. + ** + ** Returns an array of the removed children (which may be empty) + */ + function &removeAllChildren () + { + $emptyArray = array(); + + if (! $this->xnumChildren) + { + return $emptyArray; + } + + $retList =& $this->xchildren; + + $idx = 0; + while ($idx < $this->xnumChildren) + { + unset ($retList[$idx++]->xparent); + } + + $this->xchildren = array(); + $this->xnumElementChildren = 0; + $this->xnumChildren = 0; + + + return $retList; + } + + + function & remove () + { + $parent =& $this->parent(); + + if (!$parent) + { + _MiniXMLLog("XML::Mini::Element::remove() called for element with no parent set. Aborting."); + return NULL; + } + + $removed =& $parent->removeChild($this); + + return $removed; + } + + + + /* parent NEWPARENT + ** + ** The parent() method is used to get/set the element's parent. + ** + ** If the NEWPARENT parameter is passed, sets the parent to NEWPARENT + ** (NEWPARENT must be an instance of MiniXMLElement) + ** + ** Returns a reference to the parent MiniXMLElement if set, NULL otherwise. + ** + ** Note: This method is mainly used internally and you wouldn't normally need + ** to use it. + ** It get's called on element appends when MINIXML_AUTOSETPARENT or + ** MINIXML_AVOIDLOOPS or avoidLoops() > 1 + ** + */ + function &parent (&$setParent) + { + if (! is_null($setParent)) + { + /* Parents can only be MiniXMLElement objects */ + if (! $this->isElement($setParent)) + { + return _MiniXMLError("MiniXMLElement::parent(): Must pass an instance of MiniXMLElement to set."); + } + $this->xparent = $setParent; + } + + return $this->xparent; + + } /* end method parent */ + + + /* avoidLoops SETTO + ** + ** The avoidLoops() method is used to get or set the avoidLoops flag for this element. + ** + ** When avoidLoops is true, children with parents already set can NOT be appended to any + ** other elements. This is overkill but it is a quick and easy way to avoid infinite loops + ** in the heirarchy. + ** + ** The avoidLoops default behavior is configured with the MINIXML_AVOIDLOOPS define but can be + ** set on individual elements (and automagically all the element's children) with the + ** avoidLoops() method. + ** + ** Returns the current value of the avoidLoops flag for the element. + ** + */ + function avoidLoops ($setTo = NULL) + { + if (! is_null($setTo)) + { + $this->xavoidLoops = $setTo; + } + + return $this->xavoidLoops; + } + + + /* toString [SPACEOFFSET] + ** + ** toString returns an XML string based on the element's attributes, + ** and content (recursively doing the same for all children) + ** + ** The optional SPACEOFFSET parameter sets the number of spaces to use + ** after newlines for elements at this level (adding 1 space per level in + ** depth). SPACEOFFSET defaults to 0. + ** + ** If SPACEOFFSET is passed as MINIXML_NOWHITESPACES. + ** no \n or whitespaces will be inserted in the xml string + ** (ie it will all be on a single line with no spaces between the tags. + ** + ** Returns the XML string. + ** + ** + ** Note: Since the toString() method recurses into child elements and because + ** of the MINIXML_NOWHITESPACES and our desire to avoid testing for this value + ** on every element (as it does not change), here we split up the toString method + ** into 2 subs: toStringWithWhiteSpaces(DEPTH) and toStringNoWhiteSpaces(). + ** + ** Each of these methods, which are to be considered private (?), in turn recurses + ** calling the appropriate With/No WhiteSpaces toString on it's children - thereby + ** avoiding the test on SPACEOFFSET + */ + + function toString ($depth=0) + { + if ($depth == MINIXML_NOWHITESPACES) + { + return $this->toStringNoWhiteSpaces(); + } else { + return $this->toStringWithWhiteSpaces($depth); + } + } + + function toStringWithWhiteSpaces ($depth=0) + { + $attribString = ''; + $elementName = $this->xname; + $spaces = $this->_spaceStr($depth) ; + + $retString = "$spaces<$elementName"; + + + foreach ($this->xattributes as $attrname => $attrvalue) + { + $attribString .= "$attrname=\"$attrvalue\" "; + } + + + if ($attribString) + { + $attribString = rtrim($attribString); + $retString .= " $attribString"; + } + + if (! $this->xnumChildren) + { + /* No kids -> no sub-elements, no text, nothing - consider a element */ + $retString .= " />\n"; + + return $retString; + } + + + + /* If we've gotten this far, the element has + ** kids or text - consider a otherstuff element + */ + + $onlyTxtChild = 0; + if ($this->xnumChildren == 1 && ! $this->xnumElementChildren) + { + $onlyTxtChild = 1; + } + + + + if ($onlyTxtChild) + { + $nextDepth = 0; + $retString .= "> "; + } else { + $nextDepth = $depth+1; + $retString .= ">\n"; + } + + + + for ($i=0; $i < $this->xnumChildren ; $i++) + { + if (method_exists($this->xchildren[$i], 'toStringWithWhiteSpaces') ) + { + + $newStr = $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth); + + + if (! is_null($newStr)) + { + if (! ( preg_match("/\n\$/", $newStr) || $onlyTxtChild) ) + { + $newStr .= "\n"; + } + + $retString .= $newStr; + } + + } else { + _MiniXMLLog("Invalid child found in $elementName ". $this->xchildren[$i]->name() ); + + } /* end if has a toString method */ + + } /* end loop over all children */ + + /* add the indented closing tag */ + if ($onlyTxtChild) + { + $retString .= " \n"; + } else { + $retString .= "$spaces\n"; + } + return $retString; + + } /* end method toString */ + + + + + function toStringNoWhiteSpaces () + { + $retString = ''; + $attribString = ''; + $elementName = $this->xname; + + foreach ($this->xattributes as $attrname => $attrvalue) + { + $attribString .= "$attrname=\"$attrvalue\" "; + } + + $retString = "<$elementName"; + + + if ($attribString) + { + $attribString = rtrim($attribString); + $retString .= " $attribString"; + } + + if (! $this->xnumChildren) + { + /* No kids -> no sub-elements, no text, nothing - consider a element */ + + $retString .= " />"; + return $retString; + } + + + /* If we've gotten this far, the element has + ** kids or text - consider a otherstuff element + */ + $retString .= ">"; + + /* Loop over all kids, getting associated strings */ + for ($i=0; $i < $this->xnumChildren ; $i++) + { + if (method_exists($this->xchildren[$i], 'toStringNoWhiteSpaces') ) + { + $newStr = $this->xchildren[$i]->toStringNoWhiteSpaces(); + + if (! is_null($newStr)) + { + $retString .= $newStr; + } + + } else { + _MiniXMLLog("Invalid child found in $elementName"); + + } /* end if has a toString method */ + + } /* end loop over all children */ + + /* add the indented closing tag */ + $retString .= ""; + + return $retString; + + } /* end method toStringNoWhiteSpaces */ + + + /* toStructure + ** + ** Converts an element to a structure - either an array or a simple string. + ** + ** This method is used by MiniXML documents to perform their toArray() magic. + */ + function & toStructure () + { + + $retHash = array(); + $contents = ""; + $numAdded = 0; + + + + for($i=0; $i< $this->xnumChildren; $i++) + { + if ($this->isElement($this->xchildren[$i])) + { + $name = $this->xchildren[$i]->name(); + + if (array_key_exists($name, $retHash)) + + { + if (! (is_array($retHash[$name]) && array_key_exists('_num', $retHash[$name])) ) + { + $retHash[$name] = array($retHash[$name], + $this->xchildren[$i]->toStructure()); + + $retHash[$name]['_num'] = 2; + } else { + array_push($retHash[$name], $this->xchildren[$i]->toStructure() ); + + $retHash[$name]['_num']++; + } + } else { + $retHash[$name] = $this->xchildren[$i]->toStructure(); + } + + $numAdded++; + } else { + $contents .= $this->xchildren[$i]->getValue(); + } + + + } + + + foreach ($this->xattributes as $attrname => $attrvalue) + { + #array_push($retHash, array($attrname => $attrvalue)); + $retHash["_attributes"][$attrname] = $attrvalue; + $numAdded++; + } + + + if ($numAdded) + { + if (! empty($contents)) + { + $retHash['_content'] = $contents; + } + + return $retHash; + } else { + return $contents; + } + + } // end toStructure() method + + + + + + /* isElement ELEMENT + ** Returns a true value if ELEMENT is an instance of MiniXMLElement, + ** false otherwise. + ** + ** Note: Used internally. + */ + function isElement (&$testme) + { + if (is_null($testme)) + { + return 0; + } + + return method_exists($testme, 'MiniXMLElement'); + } + + + /* isNode NODE + ** Returns a true value if NODE is an instance of MiniXMLNode, + ** false otherwise. + ** + ** Note: used internally. + */ + function isNode (&$testme) + { + if (is_null($testme)) + { + return 0; + } + + return method_exists($testme, 'MiniXMLNode'); + } + + + /* createNode NODEVALUE [ESCAPEENTITIES] + ** + ** Private (?) + ** + ** Creates a new MiniXMLNode instance and appends it to the list + ** of this element's children. + ** The new child node's value is set to NODEVALUE. + ** + ** Returns a reference to the new child node. + ** + ** Note: You don't need to use this method normally - it is used + ** internally when appending text() and such data. + ** + */ + function & createNode (&$value, $escapeEntities=NULL) + { + + $newNode = new MiniXMLNode($value, $escapeEntities); + + $appendedNode =& $this->appendNode($newNode); + + return $appendedNode; + } + + + /* appendNode CHILDNODE + ** + ** appendNode is used to append an existing MiniXMLNode object to + ** this element's list. + ** + ** Returns a reference to the appended child node. + ** + ** + ** Note: You don't need to use this method normally - it is used + ** internally when appending text() and such data. + */ + function &appendNode (&$node) + { + if (is_null($node)) + { + return _MiniXMLError("MiniXMLElement::appendNode() need to pass a non-NULL MiniXMLNode."); + } + + + if (! method_exists($node, 'MiniXMLNode')) + { + return _MiniXMLError("MiniXMLElement::appendNode() must pass a MiniXMLNode object to appendNode."); + } + + if (MINIXML_AUTOSETPARENT) + { + if ($this->xparent == $node) + { + return _MiniXMLError("MiniXMLElement::appendnode() Tryng to append parent $cname as node of " + . $this->xname ); + } + $node->parent($this); + } + + + $idx = $this->xnumChildren++; + $this->xchildren[$idx] = $node; + + return $this->xchildren[$idx]; + + + } + + /* Destructor to keep things clean -- patch by Ilya */ + function __destruct() + { + for ($i = 0; $i < count($this->xchildren); ++$i) + $this->xchildren[$i]->xparent = null; + } + + +} /* end MiniXMLElement class definition */ + + + + + + +/*************************************************************************************************** +**************************************************************************************************** +***** +***** MiniXMLElementComment +***** +**************************************************************************************************** +***************************************************************************************************/ + +/* The MiniXMLElementComment class is a specific extension of the MiniXMLElement class. +** +** It is used to create the special tags and an instance in created when calling +** $elementObject->comment('this is a comment'); +** +** It's methods are the same as for MiniXMLElement - see those for documentation. +**/ + +class MiniXMLElementComment extends MiniXMLElement { + + function MiniXMLElementComment ($name=NULL) + { + $this->MiniXMLElement('!--'); + } + + + function toString ($depth=0) + { + if ($depth == MINIXML_NOWHITESPACES) + { + return $this->toStringNoWhiteSpaces(); + } else { + return $this->toStringWithWhiteSpaces($depth); + } + } + + + function toStringWithWhiteSpaces ($depth=0) + { + + $spaces = $this->_spaceStr($depth) ; + + $retString = "$spaces\n"; + + return $retString; + } + + /* If we get here, the element does have children... get their contents */ + + $nextDepth = $depth+1; + + for ($i=0; $i < $this->xnumChildren ; $i++) + { + $retString .= $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth); + } + + $retString .= "\n$spaces -->\n"; + + + return $retString; + } + + + function toStringNoWhiteSpaces () + { + $retString = ''; + + $retString = ""; + return $retString; + } + + + /* If we get here, the element does have children... get their contents */ + for ($i=0; $i < $this->xnumChildren ; $i++) + { + $retString .= $this->xchildren[$i]->toStringNoWhiteSpaces(); + } + + $retString .= " -->"; + + + return $retString; + } + + +} + + + + +/*************************************************************************************************** +**************************************************************************************************** +***** +***** MiniXMLElementCData +***** +**************************************************************************************************** +***************************************************************************************************/ + +/* The MiniXMLElementCData class is a specific extension of the MiniXMLElement class. +** +** It is used to create the special tags and an instance in created when calling +** $elementObject->cdata('data'); +** +** It's methods are the same as for MiniXMLElement - see those for documentation. +**/ + +class MiniXMLElementCData extends MiniXMLElement { + + + + + function MiniXMLElementCData ($contents) + { + + $this->MiniXMLElement('CDATA'); + if (! is_null($contents)) + { + $this->createNode($contents, 0) ; + } + } + + + function toStringNoWhiteSpaces () + { + return $this->toString(MINIXML_NOWHITESPACES); + } + + function toStringWithWhiteSpaces ($depth=0) + { + return $this->toString($depth); + } + + function toString ($depth=0) + { + $spaces = ''; + if ($depth != MINIXML_NOWHITESPACES) + { + $spaces = $this->_spaceStr($depth); + } + + $retString = "$spacesxnumChildren) + { + $retString .= "]]>\n"; + return $retString; + } + + for ( $i=0; $i < $this->xnumChildren; $i++) + { + $retString .= $this->xchildren[$i]->getValue(); + + } + + $retString .= " ]]>\n"; + + return $retString; + } + + + +} + +/*************************************************************************************************** +**************************************************************************************************** +***** +***** MiniXMLElementDocType +***** +**************************************************************************************************** +***************************************************************************************************/ + +/* The MiniXMLElementDocType class is a specific extension of the MiniXMLElement class. +** +** It is used to create the special tags and an instance in created when calling +** $elementObject->comment(''); +** +** It's methods are the same as for MiniXMLElement - see those for documentation. +**/ + +class MiniXMLElementDocType extends MiniXMLElement { + + var $dtattr; + + function MiniXMLElementDocType ($attr) + { + $this->MiniXMLElement('DOCTYPE'); + $this->dtattr = $attr; + } + function toString ($depth) + { + if ($depth == MINIXML_NOWHITESPACES) + { + return $this->toStringNoWhiteSpaces(); + } else { + return $this->toStringWithWhiteSpaces($depth); + } + } + + + function toStringWithWhiteSpaces ($depth=0) + { + + $spaces = $this->_spaceStr($depth); + + $retString = "$spacesdtattr . " [\n"; + + if (! $this->xnumChildren) + { + $retString .= "]>\n"; + return $retString; + } + + $nextDepth = $depth + 1; + + for ( $i=0; $i < $this->xnumChildren; $i++) + { + + $retString .= $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth); + + } + + $retString .= "\n$spaces]>\n"; + + return $retString; + } + + + function toStringNoWhiteSpaces () + { + + $retString = "dtattr . " [ "; + + if (! $this->xnumChildren) + { + $retString .= "]>\n"; + return $retString; + } + + for ( $i=0; $i < $this->xnumChildren; $i++) + { + + $retString .= $this->xchildren[$i]->toStringNoWhiteSpaces(); + + } + + $retString .= " ]>\n"; + + return $retString; + } + + +} + + +/*************************************************************************************************** +**************************************************************************************************** +***** +***** MiniXMLElementEntity +***** +**************************************************************************************************** +***************************************************************************************************/ + +/* The MiniXMLElementEntity class is a specific extension of the MiniXMLElement class. +** +** It is used to create the special tags and an instance in created when calling +** $elementObject->comment(''); +** +** It's methods are the same as for MiniXMLElement - see those for documentation. +**/ + +class MiniXMLElementEntity extends MiniXMLElement { + + + + function MiniXMLElementEntity ($name, $value=NULL) + { + + $this->MiniXMLElement($name); + + if (! is_null ($value)) + { + $this->createNode($value, 0); + } + + } + + function toString ($depth = 0) + { + + $spaces = ''; + if ($depth != MINIXML_NOWHITESPACES) + { + $spaces = $this->_spaceStr($depth); + } + + $retString = "$spacesname(); + + if (! $this->xnumChildren) + { + $retString .= ">\n"; + return $retString; + } + + $nextDepth = ($depth == MINIXML_NOWHITESPACES) ? MINIXML_NOWHITESPACES + : $depth + 1; + $retString .= '"'; + for ( $i=0; $i < $this->xnumChildren; $i++) + { + + $retString .= $this->xchildren[$i]->toString(MINIXML_NOWHITESPACES); + + } + $retString .= '"'; + $retString .= " >\n"; + + return $retString; + } + + + function toStringNoWhiteSpaces () + { + return $this->toString(MINIXML_NOWHITESPACES); + } + + function toStringWithWhiteSpaces ($depth=0) + { + return $this->toString($depth); + } + + +} + + +?> \ No newline at end of file diff --git a/app/helper/classes/node.inc.php b/app/helper/classes/node.inc.php new file mode 100644 index 0000000..15bec0c --- /dev/null +++ b/app/helper/classes/node.inc.php @@ -0,0 +1,289 @@ +this text is bold +** Would be represented as a MiniXMLElement named 'B' with a single +** child, a MiniXMLNode object which contains the string 'this text +** is bold'. +** +** a MiniXMLNode has +** - a parent +** - data (text OR numeric) +*/ + +class MiniXMLNode extends MiniXMLTreeComponent { + + + var $xtext; + var $xnumeric; + + /* MiniXMLNode [CONTENTS] + ** Constructor. Creates a new MiniXMLNode object. + ** + */ + function MiniXMLNode ($value=NULL, $escapeEntities=NULL) + { + $this->MiniXMLTreeComponent(); + $this->xtext = NULL; + $this->xnumeric = NULL; + + /* If we were passed a value, save it as the + ** appropriate type + */ + if (! is_null($value)) + { + if (is_numeric($value)) + { + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Setting numeric value of node to '$value'"); + } + + $this->xnumeric = $value; + } else { + if (MINIXML_IGNOREWHITESPACES > 0) + { + $value = trim($value); + $value = rtrim($value); + } + + if (! is_null($escapeEntities)) + { + if ($escapeEntities) + { + $value = htmlentities($value); + } + } elseif (MINIXML_AUTOESCAPE_ENTITIES > 0) { + $value = htmlentities($value); + } + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Setting text value of node to '$value'"); + } + + $this->xtext = $value; + + + } /* end if value numeric */ + + } /* end if value passed */ + + } /* end MiniXMLNode constructor */ + + /* getValue + ** + ** Returns the text or numeric value of this Node. + */ + function getValue () + { + $retStr = NULL; + if (! is_null($this->xtext) ) + { + $retStr = $this->xtext; + } elseif (! is_null($this->xnumeric)) + { + $retStr = "$this->xnumeric"; + } + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("MiniXMLNode::getValue returning '$retStr'"); + } + + return $retStr; + } + + + /* text [SETTO [SETTOALT]] + ** + ** The text() method is used to get or set text data for this node. + ** + ** If SETTO is passed, the node's content is set to the SETTO string. + ** + ** If the optional SETTOALT is passed and SETTO is false, the + ** node's value is set to SETTOALT. + ** + ** Returns this node's text, if set or NULL + ** + */ + function text ($setToPrimary = NULL, $setToAlternate=NULL) + { + $setTo = ($setToPrimary ? $setToPrimary : $setToAlternate); + + if (! is_null($setTo)) + { + if (! is_null($this->xnumeric) ) + { + return _MiniXMLError("MiniXMLNode::text() Can't set text for element with numeric set."); + + } elseif (! is_string($setTo) && ! is_numeric($setTo) ) { + + return _MiniXMLError("MiniXMLNode::text() Must pass a STRING value to set text for element ('$setTo')."); + } + + if (MINIXML_IGNOREWHITESPACES > 0) + { + $setTo = trim($setTo); + $setTo = rtrim($setTo); + } + + + if (MINIXML_AUTOESCAPE_ENTITIES > 0) + { + $setTo = htmlentities($setTo); + } + + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Setting text value of node to '$setTo'"); + } + + $this->xtext = $setTo; + + } + + return $this->xtext; + } + + /* numeric [SETTO [SETTOALT]] + ** + ** The numeric() method is used to get or set numerical data for this node. + ** + ** If SETTO is passed, the node's content is set to the SETTO string. + ** + ** If the optional SETTOALT is passed and SETTO is NULL, the + ** node's value is set to SETTOALT. + ** + ** Returns this node's text, if set or NULL + ** + */ + function numeric ($setToPrim = NULL, $setToAlt = NULL) + { + $setTo = is_null($setToPrim) ? $setToAlt : $setToPrim; + + if (! is_null($setTo)) + { + if (! is_null($this->xtext)) { + + return _MiniXMLError("MiniXMLElement::numeric() Can't set numeric for element with text."); + + } elseif (! is_numeric($setTo)) + { + return _MiniXMLError("MiniXMLElement::numeric() Must pass a NUMERIC value to set numeric for element."); + } + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("Setting numeric value of node to '$setTo'"); + } + $this->xnumeric = $setTo; + } + + return $this->xnumeric; + } + + + + /* toString [DEPTH] + ** + ** Returns this node's contents as a string. + ** + ** + ** Note: Nodes have only a single value, no children. It is + ** therefore pointless to use the same toString() method split as + ** in the MiniXMLElement class. + ** + */ + + function toString ($depth=0) + { + if ($depth == MINIXML_NOWHITESPACES) + { + return $this->toStringNoWhiteSpaces(); + } + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("MiniXMLNode::toString() call with depth $depth"); + } + + $spaces = $this->_spaceStr($depth); + $retStr = $spaces; + + if (! is_null($this->xtext) ) + { + /* a text element */ + $retStr .= $this->xtext; + } elseif (! is_null($this->xnumeric)) { + /* a numeric element */ + $retStr .= $this->xnumeric; + } + + /* indent all parts of the string correctly */ + $retStr = preg_replace("/\n\s*/sm", "\n$spaces", $retStr); + + return $retStr; + } + + + function toStringWithWhiteSpaces ($depth=0) + { + return $this->toString($depth); + } + + function toStringNoWhiteSpaces () + { + + if (MINIXML_DEBUG > 0) + { + _MiniXMLLog("MiniXMLNode::toStringNoWhiteSpaces() call with depth $depth"); + } + + if (! is_null($this->xtext) ) + { + /* a text element */ + $retStr = $this->xtext; + } elseif (! is_null($this->xnumeric)) { + /* a numeric element */ + $retStr = $this->xnumeric; + } + + return $retStr; + } + + +} /* end class definition */ + + + +?> \ No newline at end of file diff --git a/app/helper/classes/treecomp.inc.php b/app/helper/classes/treecomp.inc.php new file mode 100644 index 0000000..45beb10 --- /dev/null +++ b/app/helper/classes/treecomp.inc.php @@ -0,0 +1,139 @@ +xparent = NULL; + } /* end MiniXMLTreeComponent constructor */ + + + /* Get set function for the element name + */ + function name ($setTo=NULL) + { + return NULL; + } + + /* Function to fetch an element */ + function & getElement ($name) + { + return NULL; + } + + /* Function that returns the value of this + component and its children */ + function getValue () + { + return NULL; + } + + /* parent NEWPARENT + ** + ** The parent() method is used to get/set the element's parent. + ** + ** If the NEWPARENT parameter is passed, sets the parent to NEWPARENT + ** (NEWPARENT must be an instance of a class derived from MiniXMLTreeComponent) + ** + ** Returns a reference to the parent MiniXMLTreeComponent if set, NULL otherwise. + */ + function &parent (&$setParent) + { + if (! is_null($setParent)) + { + /* Parents can only be MiniXMLElement objects */ + if (! method_exists($setParent, 'MiniXMLTreeComponent')) + { + return _MiniXMLError("MiniXMLTreeComponent::parent(): Must pass an instance derived from " + . "MiniXMLTreeComponent to set."); + } + $this->xparent = $setParent; + } + + return $this->xparent; + + + } + + /* Return a stringified version of the XML representing + this component and all sub-components */ + function toString ($depth=0) + { + return NULL; + } + + /* dump + ** Debugging aid, dump returns a nicely formatted dump of the current structure of the + ** MiniXMLTreeComponent-derived object. + */ + function dump () + { + return var_dump($this); + } + + /* helper class that everybody loves */ + function _spaceStr ($numSpaces) + { + $retStr = ''; + if ($numSpaces < 0) + { + return $retStr; + } + + for($i = 0; $i < $numSpaces; $i++) + { + $retStr .= ' '; + } + + return $retStr; + } + + /* Destructor to keep things clean -- patch by Ilya */ + function __destruct() + { + $this->xparent = null; + } + +} /* end class definition */ +?> \ No newline at end of file diff --git a/app/helper/error.php b/app/helper/error.php new file mode 100644 index 0000000..757bf86 --- /dev/null +++ b/app/helper/error.php @@ -0,0 +1,287 @@ + + * @version 0.1.4 + * @copyright GPL + */ +/** + * Klasse zur Fehlerbehandlung + */ +class errorHandler { + var $object = ''; + var $method = ''; + + var $is_silent = FALSE; + var $messages; + + function errorHandler($object='Objekt', $method='Methode') { + $this->object = $object; + $this->method = $method; + $this->messages = array(); + } + + /** + * Wrapperfunktion um Ausgabe zu steuern + * + * Die Ausgabe der Funktionsaufrufe wird abhängig von der Instanzvariablen + * is_silent in eine Variable umgeleitet oder direkt ausgegeben. + * + * @param string $output + */ + function output($output) { + if ( $this->is_silent ) { + $this->messages[] = $output; + } else { + echo $output; + } + } + + /** + * Zwischenspeicher ausgeben + */ + function flush_output_cache() { + $msgs = $this->messages; + foreach( $msgs as $key=>$msg ) { + echo $msg; + unset($this->messages[$key]); + } + } + + /** + * HTML-Ausgabe unterbinden + */ + function silent() { + $this->is_silent = TRUE; + } + + /** + * Ausgabe von Meldungen ermöglichen + */ + function verbose() { + $this->is_silent = FALSE; + } + + /** + * Eine Variable ausgeben + * + * Der Inhalt der übergebenen Variable wird ausgegeben und + * ein ggf. zusätzlich übergebener Infotext wird davorgeschrieben. + * + * Wenn die Variable ein Objekt ist, werden Informationen über die + * zugrundeliegende Klasse zurückgegeben. + * + * @param mixed $var + * @param string $text optional, Standardwert ist "Variableninhalte" + */ + function sv($var, $text='Variableninhalte') { + if ( !isset($var) ) return; + + $html = '
';
+
+		if ( is_object($var) ) {
+			$object = ( $text == 'Variableninhalte' )? 'Objekt': 'Objekt '.$text;
+
+			$html .= ''.$this->object . ' - ' . $this->method . ' - '.$object.''."\n";
+			$html .= "\tDas ".$object." ist Instanz der Klasse ".get_class($var)."\n";
+
+			$html .= '
' . $object . ' - Variablen'."\n"; + #$html .= var_export( get_class_vars(get_class($var)), TRUE ); + $html .= var_export( get_object_vars($var), TRUE ); + $html .= "\n"; + + $html .= '' .$object. ' - Methoden'."\n"; + $methods = get_class_methods($var); + sort($methods); + foreach( $methods as $method ) { + $html .= " - ".$method."\n"; + } + $html .= '
'."\n"; + + } else { + $var = ( is_string($var) )? htmlspecialchars($var): $var; + + $html .= ''.$this->object . ' - ' . $this->method . ' - '.$text.''."\n"; + $html .= var_export( $var, TRUE ); + + } + + $html .='
'; + $this->output($html); + } + + /** + * einfache Textausgabe + */ + function say($text) { + $html = '
'.$text.'
'; + $this->output($html); + } + + /** + * Variable analysieren und inklusive einiger Eigenschaften ausgeben + */ + function analyze($var, $text = 'Variableninhalte') { + $this->sv($var, $text); + if (is_bool($var)) $props[] = 'boolean'; + if (is_null($var)) $props[] = 'null'; + if (is_string($var)) $props[] = 'string'; + if (is_numeric($var)) $props[] = 'numeric'; + if (is_float($var)) $props[] = 'float'; + if (is_object($var)) $props[] = 'object'; + if (is_array($var)) $props[] = 'array'; + $html .= '
Eigenschaften: ';
+		$html .= implode(', ', $props);
+		$html .= '
'; + $this->output($html); + } + + /** + * Eine Variable ausgeben und Skript beenden + * + * @param mixed $var + * @param string $text optionaler Parameter. + */ + function svaq($var, $text = 'Variableninhalte') { + $this->sv($var, $text); + $this->stop(); + } + + /** + * SQL ausgeben + */ + function sql($var, $text = 'SQL') { + $var = preg_replace('@ (BETWEEN|AND|OR) @', ' $1 '."\n", preg_replace('@(SELECT|INNER|WHERE|FROM|LIMIT|GROUP|HAVING) @',"\n".'$1 ', $var)); + $this->sv($var, $text); + } + + /** + * Superglobale $_FILES ausgeben + */ + function files() { + $this->sv($_FILES, 'Superglobale $_FILES - enthält Uploaddaten'); + } + + /** + * Superglobale $_POST ausgeben + */ + function post() { + $this->sv($_POST, 'Superglobale $_POST - enthält Formulardaten'); + } + + /** + * Superglobale $GLOBALS ausgeben + */ + function globals() { + $this->sv($GLOBALS, 'Superglobale $GLOBALS - enthält alle Variablen'); + } + + /** + * Superglobale $_SESSION ausgeben + */ + function session() { + $this->sv($_SESSION, 'Superglobale $_SESSION - enthält Sessiondaten'); + } + + /** + * Superglobale $_COOKIE ausgeben + */ + function cookies() { + $this->sv($_COOKIE, 'Superglobale $_COOKIE - enthält Cookiedaten'); + } + + /** + * Zeitmessungen + * + * Eine Beispielfunktion für die Zeiterfassung ist beigefügt, sie muss im Bedarfsfall an den Anfang der + * index.php geschrieben werden. + * + * Die Einbindung des ErrorHandler und der Aufruf der Funktion timer sollte direkt nach der Ermittlung der + * Endzeit (höhö) geschehen. Je nach Anwendungsfall kann dies in vollständig in der index.php geschehen. + * + * Man sollte sicherstellen, dass die Genauigkeit des float-Datentyps richtig eingestellt ist. Mit der Standard- + * Einstellung "precision = 12" ist man nur bis 0.01 Sekunden genau. + * In der php.ini sollte man also + * precision = 16 + * einstellen + * + * @param float $start Startzeit als Microtime + * @param float $end Endzeit (höhö) als Microtime + * @param int $interval Aktualisierungsintervall in Sekunden + */ + function timer($start, $end, $interval) { + /* + ini_set('precision', '16'); + function getmicrotime() { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } + $start = getmicrotime(); + # Code + $end = getmicrotime(); + */ + if ( $interval > 0 ) { + $interval = $interval * 1000; + } elseif ($interval == 0) { + unset($_SESSION['test']); + return; + } + + if ( !isset($_SESSION['test']['time']) ) $_SESSION['test']['time'] = 0; + if ( !isset($_SESSION['test']['count']) ) $_SESSION['test']['count'] = 0; + + $time = $this->_format_number($end - $start); + $_SESSION['test']['time'] += $time; + $avg = $this->_format_number($_SESSION['test']['time'] / ++$_SESSION['test']['count']); + $html .= '
';
+		$html .= 'Zeit für aktuellen Durchlauf: '.$time.' Sekunden (Nr. '.$_SESSION['test']['count'].")\n";
+		$html .= 'Durchschnittliche Zeit: '.$avg." Sekunden";
+		$html .= '
'; + $html .= ' + '; + + $this->output($html); + } + + + /** + * Skript anhalten + */ + function stop() { + exit(); + } + + function _format_number($number) { + return str_pad(substr(round($number, 5), 0, 7), 7, '0'); + } +} +?> diff --git a/app/helper/html.php b/app/helper/html.php new file mode 100644 index 0000000..f195a08 --- /dev/null +++ b/app/helper/html.php @@ -0,0 +1,354 @@ +set_data( $view->get_data_object() ); + } + + $this->eol = ( $eol )? PHP_EOL: ''; + $this->output_xhtml = (boolean) $output_xhtml; + } + + /** + * Datenquelle setzen + * + * @param mixed $data + */ + public function set_data($data) { + $this->data = $data; + } + + /** + * HTML ausgeben + * + * @param string $html + */ + protected function output($html) { + if ( $this->output_xhtml === false ) { + $html = str_replace(' />', '>', $html); + } + + echo $html . $this->eol; + } + + /** + * Formulartag erzeugen + * + * @param string $action + * @param string $id + * @param string $target + * @param string $method + * @param string $charset + */ + public function form_tag($action, $id='', $target='', $method='post', $charset='UTF-8') { + $action = ( $action[0] == '/' )? $action: '/'.$action; + $id = ( $id != '' )? ' id="'.$id.'" name="'.$id.'" ': ''; + $target = ( $target != '' )? ' target="'.$target.'" ': ''; + + $html = '
'; + $this->output($html); + } + /** + * Formulartag schließen + */ + public function form_end() { + $html = '
'; + $this->output($html); + } + + /** + * Dropdown erzeugen + * + * Es wird ein HTML-Dropdown erzeugt. Die einzelnen Dropdownelemente werden + * als kommaseparierte Liste in folgendem Format übergeben: + * 1=eins,2=zwei,3=drei + * + * Dies führt zu einem Dropdown mit drei Elementen. Es wird der Text nach dem + * Gleichheitszeichen zur Darstellung verwendet, hier also + * 'eins', 'zwei', 'drei'. + * Die übergebenen Werte sind dabei der Text vor dem Gleichheitszeichen: + * 1, 2, 3. + * + * Das Dropdown hat die ID, die im ersten Parameter übergeben wird und + * verwendet diesen auch zur Datenübergabe als Array-Schlüssel. + * + * Wenn bereits Daten geladen wurden, wird versucht, den entsprechenden + * Wert als vorausgewählt darzustellen. + * + * Das HTML wird ausgegeben. + * + * @param string $field Eindeutiger Bezeichner für das Datenfeld. + * @param string $options Dropdownelemente im Format value=description, kommasepariert + * @param string $label Beschriftung des Dropdowns + */ + public function get_dropdown($field, $options, $label='') { + if ( is_string($options) ) { + $options = $this->string_to_array($options); + } + + $html = ''; + + if ( $label != '') $html .= $this->get_label($field, $label); + + $html .= ''; + + $this->output($html); + } + + /** + * Dropdown-String zu Array machen + * + * @param string $string + * @return array + */ + protected function string_to_array($string) { + $array = array(); + + foreach( explode(',', $string) as $keyvaluepair ) { + if ( strpos( $keyvaluepair, '=' ) === false ) { + $id = $name = $keyvaluepair; + } else { + list($id, $name) = explode('=', $keyvaluepair, 2); + } + + $array[] = array( + 'id'=>$id, + 'name'=>$name + ); + } + + return $array; + } + + /** + * Dropdown-Array zu String machen + * + * @param array $data + * @return string + */ + protected function array_to_string($data) { + foreach( $data as $value) { + $string[] = $value['id'].'='.$value['name']; + } + + $string = implode(',', $string); + + return $string; + } + + + /** + * Radiobuttons ausgeben + * + * Radiobuttons werden direkt ausgegeben. + * Wrapperfunktion für echo html::return_radios() + */ + public function get_radios($field, $options, $tag='p') { + $html = $this->return_radios($field, $options, $tag); + + $this->output($html); + } + + /** + * Radiobuttons erzeugen + * + * @todo Dokumentation erstellen + */ + public function return_radios($field, $options, $tag='p') { + $options = explode(',', $options); + $html = ''; + + foreach( $options as $option ) { + $option = explode('=', $option); + $option[1] = ( isset($option[1]) )? $option[1]: $option[0]; + $value = $this->get_value('1', $option); + + $selected = ( $this->get_value($field, $this->data) == $option[0] )? ' checked="checked"': ''; + $html .= "\n\t\t\t".'<'.$tag.'>' .$this->get_label($field.'-'.$option[0], $value) . ''; + } + + return $html; + } + + /** + * Inputfeld erzeugen + * + * Das erzeugte HTML wird direkt ausgegeben. + * + * @param string $field ID des Formularfelds + * @param string $label zu verwendendes Label + * @param array $options Optionen als assoziatives Array: + * - type: von text abweichender Typ + * - size: Länge (inkl. Maximallänge) einstellen + */ + public function get_input($field, $label='', $options=array() ) { + if ( !empty($options) ) { + $type = ( isset($options['type']) AND !empty($options['type']) )? + 'type="'.$options['type'].'"': + 'type="text"'; + $options = ( isset($options['size']) AND !empty($options['size']) )? + 'maxlength="'.$options['size'].'" size="'.$options['size'].'" ': + ''; + } else { + $type = 'type="text"'; + $options = ''; + } + + $html = ''; + if ( $label != '' AND !is_numeric($label) ) { + $html .= $this->get_label($field, $label); + } + + $name = ( $type == 'type="file"' )? + $field: + 'fl['.$field.']'; + + $value = $this->get_value($field, $this->data); + + $html .= ''; + + $this->output($html); + } + + /** + * Verstecktes Inputfeld erzeugen + * + * @param string $field + * @param string $value + */ + public function get_hidden($field, $value) { + $html = ''; + $this->output($html); + } + + /** + * Button erzeugen + * + * @param string $name ID und name des Buttons + * @param string $label optional: Beschriftung + * @param string $type optional: von "submit" abweichender Typ + */ + public function get_button($name, $label='', $type='submit') { + $label = ( $label === '' )? $name: $label; + + $html = ''; + $this->output($html); + } + /** + * Checkbox erzeugen + * + * @param string $field ID des Formularfelds + * @param string $label zu verwendendes Label + * @return string + */ + public function get_checkbox($field, $label='') { + $html = ''; + $data = $this->get_value($field, $this->data); + + $checked = ( $data == $field OR $data == 1 )? + ' checked="checked"': + ''; + + $html .= ' '; + + if ( $label != '' AND !is_numeric($label) ) { + $html .= ''; + } + + $this->output($html); + } + + /** + * Textarea erzeugen + * + * Es wird ein mehrzeiliges Eingabefeld erzeugt. + * + * @param string $field + * @param string $label + * @param array $options Hash mit Optionen: + * - rows: Anzahl der Zeilen + * - cols: Anzahl der Spalten + */ + public function get_textarea($field, $label='', $options = array() ) { + $html = ''; + $rows = ( isset($options['rows']) AND !empty($options['rows']) )? $options['rows']: 5; + $cols = ( isset($options['cols']) AND !empty($options['cols']) )? $options['cols']: 30; + + $value = $this->get_value($field, $this->data); + + if ( $label != '' ) $html .= $this->get_label($field, $label); + + $html .= ''; + + $this->output($html); + } + + /** + * Formularvorgabewert oder -beschriftung holen + * + * @param string $field + * @param mixed $source + * @param string $default + * @return string + */ + protected function get_value($field, $source, $default = '') { + if ( $source instanceof view_data ) { + $source->set_raw_output(false); + $source->set_default($default); + $value = $source->get($field, 'string'); + $source->set_default(''); + return $value; + } elseif ( $source instanceof data_wrapper ) { + return $source->is_set($field) ? $source->get($field): $default; + } + + if ( !is_array($source) AND !($source instanceof ArrayAccess) ) { + $source = (array) $source; + } + + return isset($source[$field]) ? $source[$field]: $default; + } + + /** + * Label erzeugen + * + * @param string $id + * @param string @value + * @return string + */ + public function get_label( $id, $value ) { + $label = ''; + + return $label; + } +} diff --git a/app/helper/mail.php b/app/helper/mail.php new file mode 100644 index 0000000..b7bb9a9 --- /dev/null +++ b/app/helper/mail.php @@ -0,0 +1,333 @@ + + * @version 0.3 + * @license MIT-License + */ +class e_mail { + /** + * variables + */ + var $text = FALSE; + var $html = FALSE; + var $attachments = FALSE; + + var $config; + + /** + * storage for error-messages + */ + var $error; + + /** + * data-parts of e-mail + */ + var $message_header; + var $message_body; + + /** + * contructor + */ + function e_mail() { + ini_set('track_errors', '1'); + } + + /** + * set configuration + * + * @param string $to + * @param string $from + * @param string $topic + * @param string $replyto [optional] + */ + function set_config($to, $from, $topic, $replyto='') { + $this->config = array( + 'to'=>$to, + 'from'=>$from, + 'topic'=>$topic + ); + + if ( $replyto != '' ) $this->config['replyto'] = $replyto; + } + + /** + * get last error-message + */ + function get_error() { + return array_pop($this->error); + } + + /** + * check wether it has to be a mime-mail or not + * + * @return boolean + */ + function must_be_mime() { + $must_be_mime = FALSE; + + if ( $this->html != FALSE + OR $this->attachments != FALSE) { + $must_be_mime = TRUE; + } + + return $must_be_mime; + } + + /** + * set text-part + */ + function set_text($txt) { + $this->text = (string) $txt; + } + /** + * set html-part + */ + function set_html($html) { + $this->html = (string) $html; + } + + /** + * add an attachment + * + * @param string $filename + * @param string $mime [optional] + * @return boolean + */ + function add_attachment($filename, $mime='') { + if ( empty($filename) ) { + $this->error[] = 'No Filename provided'; + return FALSE; + } + if ( !is_file($filename) ) { + $this->error[] = $filename . ' not found.'; + return FALSE; + } + + if ( $mime == '') { + // trying to find the mime-type + if ( function_exists('mime_content_type') ) { + $mime = mime_content_type($filename); + } else { + $this->error[] = 'No mime-type provided and unable to guess it.'; + return FALSE; + } + } + + // saving the data + $file = array( + 'name'=>$filename, + 'mime'=>$mime + ); + + if ( $this->attachments === FALSE ) { + $this->attachments = array(); + } + + $this->attachments[] = $file; + + return TRUE; + } + + /** + * unset vars + */ + function clean_vars() { + $this->text = FALSE; + $this->html = FALSE; + $this->attachments = FALSE; + } + + /** + * parse template + * + * The template is filled with data. For every key in the + * data-array, a substitution is attempted. + * + * {NAME} will be replaced with $data['name'] + * + * All remaining templatetags will be removed. + * + * The resulting string will be returned. + * + * @param string $template + * @param array $data + * @return string + */ + function parse_template($template, $data) { + $content = $template; + + // substitute templatetags + foreach( $data as $key => $value) { + $content = str_replace('{'.strtoupper($key).'}', $value, $content); + } + + // discard unused templatetags + $content = preg_replace('/{[-_a-z]*}/i', '', $content); + + return $content; + } + + /** + * composition of mail-headers and body + * + * the e-mail-composition consists of the following steps: + * + * - Check wether (or not) a mime-mail is necessary, if yes: + * - check if attachments have to be handled, if yes: + * - set header to multipart/mixed + * - generate and add outer boundary + * - set header to multipart/alternative and generate boundary + * - plaintext-part generate if none set. + * - compose body + * - mark end of body + * - check if attachments have to be handled, if yes: + * - add attachments and boundaries + * - mark end of mail + * + * - always: + * - save header in message_header + * - save body in message_body + * - clean temporary variables + */ + function compose_message() { + $headers[] = 'From: '.$this->config['from']; + if ( isset($this->config['replyto']) ) $headers[] = 'Reply-To: '.$this->config['replyto']; + + if ( $this->must_be_mime() ) { + $headers[] = 'MIME-Version: 1.0'; + $boundary = md5(uniqid(date('d.m.Y \u\m H:i',mktime() ))); + + if ( $this->attachments != FALSE ) { + //tell e-mail client this e-mail contains more than one part + $headers[] = 'Content-Type: multipart/mixed; boundary="main'.$boundary."\"\r\n"; + $headers[] = '--main'.$boundary; + } + //tell e-mail client this e-mail contains alternate versions + $headers[] = 'Content-Type: multipart/alternative; boundary="sub'.$boundary."\"\r\n"; + + //plain text part of message + if ( empty($this->text) ) { + $this->text = strip_tags($this->html); + } + $body = '--sub'.$boundary."\r\n" . + "Content-Type: text/plain; charset=ISO-8859-1\r\n" . + "Content-Transfer-Encoding: base64\r\n\r\n"; + $body .= chunk_split(base64_encode($this->text)); + + //html part of message + $body .= "\r\n\r\n".'--sub'.$boundary."\r\n" . + "Content-Type: text/html; charset=ISO-8859-1\r\n" . + "Content-Transfer-Encoding: base64\r\n\r\n"; + $body .= chunk_split(base64_encode($this->html)); + + //end of message + $body .= "\r\n".'--sub'.$boundary."--\r\n\r\n."; + + if ($this->attachments != FALSE ) { + //attachments of message + $files = $this->attachments; + + foreach ( $files as $file ) { + $body .= "\r\n--main".$boundary."\r\n". + "Content-Type: " . $file['mime']. "\r\n" . + "Content-Transfer-Encoding: base64\r\n" . + "Content-Disposition:attachment\r\n\r\n"; + $body .= chunk_split(base64_encode( file_get_contents($file['name']) )); + } + $body .= '--main'.$boundary."--\r\n\r\n."; + } + + } else { + $body = $this->text; + + } + + $this->message_body = $body; + $this->message_header = implode("\r\n", $headers); + + $this->clean_vars(); + } + + /** + * send mail + */ + function send_mail() { + if ( empty($this->message_body) + OR empty($this->message_header) + OR empty($this->config) + ) { + $this->error[] = 'Unvollständige Daten'; + return FALSE; + } + + $mailed = @mail( + $this->config['to'], + $this->config['topic'], + $this->message_body, + $this->message_header + ) OR $this->error[] = $php_errormsg; + + return $mailed; + } + + /** + * send an email + * + * @param array $data Array with the following keys: + * - text messagebody as text/plain + * - html messagebody as text/html + * - css CSS for the HTML-part + * @param array $config Array with the following keys: + * - mailfrom + * - replyto + * - mailtopic + * - mailreceipient + */ + function compose_and_send($data, $config) { + $headers = 'From: '.$config['mailfrom']."\r\n"; + $headers .= 'Reply-To: '.$config['replyto']."\r\n"; + $headers .= 'MIME-Version: 1.0'."\r\n"; + + $boundary = md5(uniqid(date('d.m.Y \u\m H:i',mktime() ))); + + //tell e-mail client this e-mail contains//alternate versions + $headers .= 'Content-Type: multipart/alternative; boundary="'.$boundary."\"\r\n\r\n"; + + $content = $data['text']; + + $htmlcontent = ''.$config['mailtopic'].''."\n".''."\n".'
'."\n"; + $htmlcontent .= $data['html']; + $htmlcontent .= "\n".'
'; + + //plain text part of message + $body = '--'.$boundary."\r\n" . + "Content-Type: text/plain; charset=ISO-8859-1\r\n" . + "Content-Transfer-Encoding: base64\r\n\r\n"; + $body .= chunk_split(base64_encode($content)); + + //html part of message + $body .= "\r\n\r\n".'--'.$boundary."\r\n" . + "Content-Type: text/html; charset=ISO-8859-1\r\n" . + "Content-Transfer-Encoding: base64\r\n\r\n"; + $body .= chunk_split(base64_encode($htmlcontent)); + + //end of message + $body .= "\r\n".'--'.$boundary."--\r\n\r\n."; + + $mailed = ( mail($config['mailreceipient'], $config['mailtopic'], $body, $headers) )? TRUE: FALSE; + + return($mailed); + } +} +?> diff --git a/app/helper/minixml.php b/app/helper/minixml.php new file mode 100644 index 0000000..f50b662 --- /dev/null +++ b/app/helper/minixml.php @@ -0,0 +1,132 @@ + and < and & in text, 0 to turn it off */ + + + +define("MINIXML_AUTOSETPARENT", 0); /* Set to 1 to automatically register parents elements with children */ + +define("MINIXML_AVOIDLOOPS", 0); /* Set to 1 to set the default behavior of 'avoidLoops' to ON, 0 otherwise */ + +define("MINIXML_IGNOREWHITESPACES", 1); /* Set to 1 to eliminate leading and trailing whitespaces from strings */ + + +/* Lower/upper case attribute names. Choose UPPER or LOWER or neither - not both... UPPER takes precedence */ +define("MINIXML_UPPERCASEATTRIBUTES", 0); /* Set to 1 to UPPERCASE all attributes, 0 otherwise */ +define("MINIXML_LOWERCASEATTRIBUTES", 0); /* Set to 1 to lowercase all attributes, 0 otherwise */ + + +/* fromFile cache. +** If you are using lots of $xmlDoc->fromFile('path/to/file.xml') calls, it is possible to use +** a caching mechanism. This cache will read the file, store a serialized version of the resulting +** object and read in the serialize object on subsequent calls. +** +** If the original XML file is updated, the cache will automatically be refreshed. +** +** To use caching, set MINIXML_USEFROMFILECACHING to 1 and set the +** MINIXML_FROMFILECACHEDIR to a suitable directory in which the cache files will +** be stored (eg, "/tmp") +**/ +define("MINIXML_USEFROMFILECACHING", 0); +define("MINIXML_FROMFILECACHEDIR", "/tmp"); + + +define("MINIXML_DEBUG", 0); /* Set Debug to 1 for more verbose output, 0 otherwise */ + + +/***************************************** end Configuration ***************************************/ + +define("MINIXML_USE_SIMPLE", 0); + +define("MINIXML_VERSION", "1.3.0"); /* Version information */ + +define("MINIXML_NOWHITESPACES", -999); /* Flag that may be passed to the toString() methods */ + + + +$MiniXMLLocation = dirname(__FILE__); +define("MINIXML_CLASSDIR", "$MiniXMLLocation/classes"); +require_once(MINIXML_CLASSDIR . "/doc.inc.php"); + + +/*************************************************************************************************** +**************************************************************************************************** +***** +***** Global Helper functions +***** +**************************************************************************************************** +***************************************************************************************************/ + + +function _MiniXMLLog ($message) +{ + error_log("MiniXML LOG MESSAGE:\n$message\n"); +} + + + + + +function _MiniXMLError ($message) +{ + error_log("MiniXML ERROR:\n$message\n"); + + return NULL; + +} + + +function _MiniXML_NumKeyArray (&$v) +{ + if (! is_array($v)) + { + return NULL; + } + + + $arrayKeys = array_keys($v); + $numKeys = count($arrayKeys); + $totalNumeric = 0; + for($i=0; $i<$numKeys; $i++) + { + if (is_numeric($arrayKeys[$i]) && $arrayKeys[$i] == $i) + { + $totalNumeric++; + } else { + return 0; + } + } + + if ($totalNumeric == $numKeys) + { + // All numeric - assume it is a "straight" array + return 1; + } else { + return 0; + } +} + + + + + + + +?> \ No newline at end of file diff --git a/app/helper/validation.php b/app/helper/validation.php new file mode 100644 index 0000000..0aa2b45 --- /dev/null +++ b/app/helper/validation.php @@ -0,0 +1,238 @@ +retrieve('language', '*', "tld = '".LANG."'"); + foreach( $result as $key => $value) { + if ( substr($key, 0, 6) != 'error_' ) continue; + $id = substr($key, 6); + + if ( !$this->rule_exists($id) ) $this->create_rule($id); + $this->update_rule($id, FALSE, $value); + } + } + + /** + * Prüfausdruck hinzufügen + * + * Prüfausdruck wird zur Liste hinzugefügt. Der Rückgabewert zeigt an, + * ob das erfolgreich war. + * + * @param string $id ID des zu überprüfenden Datenfeldes + * @param string $type Art der Überprüfung. Gültige Werte sind + * - string + * - number + * - email + * - regexp + * @param string $rule zusätzliche Überprüfungsregel + * mögliche Werte sind + * - optional + * - multiline + * - [eine Mengenangabe nach RegEx-Syntax] + * - [ein regulärer Ausdruck] + * @return boolean + */ + function set_rule($id, $type, $rule='') { + if ( !is_string($id) ) $id = (string) $id; + if ( !is_string($type) ) $type = (string) $type; + if ( !is_string($rule) ) $rule = (string) $rule; + + $start = '/^'; + $end = '$/'; + + switch ($type) { + case 'string': + $regexp = '[- _a-zA-ZäüößÄÖÜ]'; + break; + + case 'number': + $regexp = '[- 0-9]'; + break; + + case 'email': + $regexp = '([A-Za-z0-9](([\w.-][^._-]*){0,61})[A-Za-z0-9])@([A-Za-z0-9]([A-Za-z0-9-]{0,61})?[A-Za-z0-9]\.)+([A-Za-z]{2,6})'; + break; + + case 'regex': + case 'regexp': + $regexp = $rule; + $start = ''; + $end = ''; + $rule = ''; + break; + + default: + $regexp = '.'; + break; + } + + if ( preg_match('/(\{[,0-9]+\}|[*+?]{1,2})/', $rule) ) { + $count = $rule; + } elseif ( $type != 'regexp' AND $type != 'regex' ) { + $rule .= ' '; + $pieces = explode(' ', $rule); + if ( in_array('optional', $pieces) ) { + $count = '*'; + } else { + $count = '+'; + } + + if ( in_array('multiline', $pieces) ) $end = $end . 'm'; + } else { + $count = ''; + } + + if ( !$this->rule_exists($id) ) $this->create_rule($id); + $this->update_rule($id, $start . $regexp . $count . $end, FALSE); + return TRUE; + } + + /** + * Fehlermeldung zu einer Prüfregel hinzufügen + * + * @param string $id ID des zu überprüfenden Datenfeldes + * @param string $msg Fehlermeldung, falls die Prüfung Eingabefehler + * feststellt + * @return boolean + */ + function set_msg($id, $msg) { + if ( !is_string($id) ) $id = (string) $id; + if ( !is_string($msg) ) $msg = (string) $msg; + + if ( !$this->rule_exists($id) ) $this->create_rule($id); + $this->update_rule($id, FALSE, $msg); + return TRUE; + } + + /** + * Formulardaten validieren + * + * Die Formulardaten werden anhand regulärer Ausdrücke auf Plausibilität + * geprüft. + * + * @param array &$data Referenz auf Formulardaten + * @return array + */ + function validate_form(&$data) { + if ( !is_array($data) ) return FALSE; + + $rules = $this->get_rules(); + if ( empty($rules) ) return FALSE; + $errors = array(); + + foreach( $rules as $field=>$rule ) { + if ( !preg_match($rule['regexp'], $data[$field]) ) { + # unset($data['field']); + $errors[] = $rule['error']; + } + } + + return $errors; + } + + /** + * Javascript mit Regeln für die Formulardatenvalidierung zurückgeben + * + * Es wird eine JS mit den Regeln für die Validierung der Formulardaten + * zurückgegeben. + * Außerdem wird der HTML-Code für das Einbinden des allgemeinen + * Validierungsskripts angefügt. + * + * @return string + */ + function get_js() { + $form_variables = $this->get_rules(); + if ( empty($form_variables) ) return FALSE; + + $js = "var validationSet = {\n"; + $entries = array(); + foreach ($form_variables as $name => $properties) { + $entries[] = "\t'".$name."': { 'regexp': ".$properties['regexp'].", 'error': ' ".addslashes($properties['error'])."'}"; + } + $js .= implode(",\n", $entries) . "\n"; + $js .= "}\n"; + + $html = ''."\n"; + $html .= ''."\n"; + return $html; + } + + ################### Verwaltungsfunktionen ########################### + /** + * Prüfen, ob Regel existiert + * + * @param string $id + * @return boolean + */ + function rule_exists($id) { + return ( isset($this->rules[$id]) ); + } + + /** + * Regelarray erzeugen + * + * @param string $id + */ + function create_rule($id) { + if ( $this->rule_exists($id) ) return; + + $this->rules[$id] = array( + 'regexp'=>'/.*/', + 'error'=>'Error in '.$id + ); + } + + /** + * Regel aktualisieren + */ + function update_rule($id, $regex=FALSE, $msg=FALSE) { + if ( !$this->rule_exists($id) ) return; + + if ( $regex !== FALSE ) $this->rules[$id]['regexp'] = $regex; + if ( $msg !== FALSE ) $this->rules[$id]['error'] = $msg; + } + + /** + * Regel entfernen + */ + function remove_rule($id) { + if ( !$this->rule_exists($id) ) return; + + unset ($this->rules[$id]); + } + + /** + * Regeln als Array zurückgeben + */ + function get_rules() { + return $this->rules; + } + ############### Ende der Verwaltungsfunktionen ###################### +} +?> diff --git a/app/modules/about/controller.php b/app/modules/about/controller.php new file mode 100644 index 0000000..e0e686c --- /dev/null +++ b/app/modules/about/controller.php @@ -0,0 +1,37 @@ +data['title'] = 'Über 2erlei'; + } + + function pressemitteilungen() { + $this->data['title'] = 'Pressemitteilungen'; + } + + function partner() { + $this->data['title'] = 'Partner'; + } + + function jobs() { + $this->data['title'] = 'Jobs'; + } + + function common() { + $bild = ( $this->cap['action'] == 'defaultAction' )? $this->defaultAction: $this->cap['action']; + $this->data['kopfbild'] = $bild; + return TRUE; + } +} +?> diff --git a/app/modules/about/help.xml b/app/modules/about/help.xml new file mode 100644 index 0000000..08e4592 --- /dev/null +++ b/app/modules/about/help.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/modules/about/layouts/default.php b/app/modules/about/layouts/default.php new file mode 100644 index 0000000..e5ab853 --- /dev/null +++ b/app/modules/about/layouts/default.php @@ -0,0 +1,36 @@ + + + + + 2erlei Medienagentur +get_element('header'); ?> + + +
+
+

2erlei Medienagentur

+ +
+ get_element('kundennavi'); ?> + +
+ + + + +
+ +
+get_sub_view(); ?> +
+ +
+ get_element('unten'); ?> + +
+
get_element('google_analytics'); ?> + get_element('lightbox'); ?> + diff --git a/app/modules/about/model.php b/app/modules/about/model.php new file mode 100644 index 0000000..4d3980e --- /dev/null +++ b/app/modules/about/model.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/about/modul.php b/app/modules/about/modul.php new file mode 100644 index 0000000..93d68bc --- /dev/null +++ b/app/modules/about/modul.php @@ -0,0 +1,17 @@ + + * @version 0.1.7 + * @license All Rights Reserved + */ + +/** + * Allgemeines zum Modul + */ +class about_modul extends fl_modul { +} +?> diff --git a/app/modules/about/view.php b/app/modules/about/view.php new file mode 100644 index 0000000..50fb563 --- /dev/null +++ b/app/modules/about/view.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/about/views/company.php b/app/modules/about/views/company.php new file mode 100644 index 0000000..3a36ec2 --- /dev/null +++ b/app/modules/about/views/company.php @@ -0,0 +1,27 @@ + + +
+

2erlei das Unternehmen

+ +

Wir sind jung, dynamisch, flexibel und in ein Netzwerk von Kompetenzen integriert. Unsere qualitativ hochwertige Tätigkeit hat ihren Schwerpunkt in den Bereichen Design und Webapplikationen.

+ +

Die kompetenten Mitarbeiter von 2erlei verbindet das Ziel, die Effiziens- und Umsatzsteigerung unserer Kunden zu fördern und zu steigern. Dass wir darin erfolgreich sind, können unsere zufriedenen Auftraggeber bestätigen.

+ +

Unsere Philosophie gründet auf Zusammenarbeit und Vernetzung. Wir klären mit Ihnen ab, welche Funktionen Sie benötigen. Darauf bauend erstellen wir ein System, das sich genau Ihren Bedürfnissen anpasst.
Das Fundament bildet unser baseContent, das wir parallel zu anderen Systemen ständig weiter entwickeln und mit ihnen vernetzen können. Durch diese Strategie der Schnittstellen bekommen Sie exakt die Kompetenzen zugespielt, die Sie benötigen. Überflüssige Ressource-Apparatur entfällt.

+ +

Wir verstehen es, komplexe Systeme übersichtlich und benutzerfreundlich zu gestalten.

+ +

 

+
+ +
+

baseContent Demo

+

Demo 2erlei

+

Benutzername: demo

+

Passwort: demo

+
diff --git a/app/modules/about/views/jobs.php b/app/modules/about/views/jobs.php new file mode 100644 index 0000000..a75d374 --- /dev/null +++ b/app/modules/about/views/jobs.php @@ -0,0 +1,34 @@ + + +
+

Jobangebote

+

Wir suchen:

+
Programmierer/in: PHP und MySQL-Datenbanken
+

Wir suchen eine Programmiererin oder Programmierer für projektbezogenes Arbeiten.

+

Tätigkeitsfeld:

+

Die 2erlei GbR ist ein junges aufstrebendes Unternehmen, das sich auf die Programmierung von Content Management Systemen spezialisiert hat. +Design für Druck und digitale Medien ist unser zweites Standbein. +Unser CMS haben wir komplett selbst entwickelt und bieten unseren Kunden spezielle Lösungen an, +die im Design sowie in der Struktur an den Kunden angepasst werden.

+

Anforderungen:

+
    +
  • sicherer Umgang mit objektiorientiertes PHP, mySQL, Ruby, CSS, HTML, Javascript, Linux Know-How für Webserver Administration
  • +
  • Seriösität, Integrität und Zuverlässigkeit sind unbedingte Voraussetzung wie eine ergebnisorientierte und umsichtige Arbeitsweise
  • +
  • Englisch in Wort und Schrift da Internationale Projekte zu absolvieren sind.
  • +
  • mind. 1jährige Berufserfahrung im Entwicklerumfeld
  • +
+
+

Bewerbungen an jobs@2erlei.de.

+ +
+ +
+

Kontakt

+

Jobangebot PDF

+
+ diff --git a/app/modules/about/views/partner.php b/app/modules/about/views/partner.php new file mode 100644 index 0000000..584e0d1 --- /dev/null +++ b/app/modules/about/views/partner.php @@ -0,0 +1,51 @@ + + + +
+ +

2erlei und ihre Partner

+ +
+
nanoLogika Logo
+
+

nanoLogika

+
Produzent für komplexe Produktkonfiguratoren
+

Am Mooskissen 25
D-14532 Kleinmachnow
http://www.nanologika.de

+
+
+ +
+
travelClips Logo
+
+

Travel Clips Videoproduktion

+
Videoproduktion speziell Kurz- und Werbeclips
+

Franz-Mehring Platz 1
D-10243 Berlin
http://www.travel-clips.de

+
+
+ +
+
GIATA Logo
+
+

GIATA mbH

+
Contentlieferant in der Tourismusbranche
+

Schlesischestr. 26
D-10997 Berlin
http://www.giata.de

+
+
+ +
+
1und1 Logo
+
+

1&1 Internet AG

+
Hosting und Telekomunikation
+

Elgendorfer Straße 57
D-56410 Montabaur
http://1und1.de

+
+
+
+ + + diff --git a/app/modules/about/views/pressemitteilungen.php b/app/modules/about/views/pressemitteilungen.php new file mode 100644 index 0000000..e2983ec --- /dev/null +++ b/app/modules/about/views/pressemitteilungen.php @@ -0,0 +1,25 @@ + + +
+ +

Pressemitteilungen

+ +
+
 
+
+

12. April 2007

+
neues Videoportal online: myHotelVideo
+

Ein weiteres interessantes Webprojekt ist heute online gegangen. myHotelVideo ist eine Reise- und Informationsplattform, wo jeder sein eigenes Hotelvideo hochladen und die Videos anderer anschauen kann.
http://www.myhotelvideo.com

+
+
+
+ +
+

Kontakt

+
+ diff --git a/app/modules/basecontent/controller.php b/app/modules/basecontent/controller.php new file mode 100644 index 0000000..85f8ddc --- /dev/null +++ b/app/modules/basecontent/controller.php @@ -0,0 +1,237 @@ +check_login('basecontent/'); + $this->data['title'] = 'Administration'; + } + + /** + * Papierkorb + * + * @todo Parameter für Aktionen einbauen + * @todo Datenvorbereitung durch das Model + * @todo relevante Module in Konfigurationsdatei auslagern + * @todo nach erotikdatenbank portieren + */ + function trashcan($param) { + $this->check_login('basecontent/trashcan/'); + $this->data['title'] = 'Papierkorb'; + + /* module auflisten, die status 2 haben können + $modules = array( + 'Firmen'=>'company_LANG', + 'Firmenarten'=>'company_cat_LANG', + 'Lokalbereiche'=>'localarea', + 'Länder'=>'localarea_cat_LANG', + 'Profile'=>'profiles_LANG', + 'Sprachen'=>'language' + ); + */ + $modules = array( + 'Accounts'=>'account' + ); + + // Daten sammeln + $trashcan_data = $this->model->get_trashcan_data($modules); + $this->data += $trashcan_data; + } + + function login($from) { + $this->data['title'] = 'Anmelden'; + $this->data['from'] = (string) $from; + $this->layout = 'loginout'; + } + + /** + * Anzeige der Fehlermeldung "Nicht berechtigt" + */ + function notallowed() { + $this->data['title'] = 'Keine Berechtigung'; + } + + function auth() { + $fl = $_POST['fl']; + + if ( isset($_SESSION['username']) OR $this->model->login($fl) ) { + $_SESSION['username'] = $fl['username']; + $_SESSION['IP'] = $_SERVER['REMOTE_ADDR']; + + $result = $this->datamodel->retrieve('user', 'level', 'name = "'.$_SESSION['username'].'"'); + $_SESSION['userlevel'] = $result['level']; + $this->flash('Willkommen, '.$_SESSION['username'].'!'); + $this->logaction( $_SESSION['username'].' hat sich eingeloggt' ); + + if ( empty($fl['from']) ) { + $this->data = array('title'=>'Administrationsbereich'); + $this->goToTarget('basecontent/'); + } else { + $this->goToTarget($fl['from']); + } + + } else { + $this->flash('Falscher Benutzername oder falsches Passwort angegeben.'); + $this->data['from'] = $fl['from']; + $this->data['title'] = 'Einloggen'; + $this->layout = 'loginout'; + $this->view = 'login'; + } + } + + function logout() { + $this->check_login('basecontent/'); + $this->layout = 'loginout'; + $this->logaction($_SESSION['username'].' hat sich ausgeloggt'); + $this->data['title'] = 'Ausgeloggt'; + + // datenbank aufraeumen + //$this->clean_db(); + + session_destroy(); + } + + function options($action) { + $this->check_login('basecontent/options/'); + $this->data['title'] = 'Einstellungen bearbeiten'; + + if( $action == 'save') { + $fl = $_POST['fl']; + $failures = 0; + $result = array(); + + foreach( $fl as $key => $value ) { + $temp = explode('_', $key); + + $data['optionname'] = strtoupper($temp[1]); + $data['value'] = $value; + $module = $temp[0].'_options'; + + $optionresult = $this->datamodel->retrieve( $module , 'id', "optionname = '".$data['optionname']."'", '', '1'); + $id = $optionresult['id']; + + if ( $this->datamodel->update($module, $data, $id) ) { + $result[] = ucwords( $temp[1] ) . ' aktualisiert: ' . $data['value']; + } else { + $result[] = 'Option ' . ucwords( $temp[1] ) . ' konnte nicht aktualisiert werden.'; + $failures++; + } + } + + $msg = ( $failures == 0 ) ? + 'Optionen wurden aktualisiert': + implode("\n", $result); + $this->flash($msg); + + $this->data['title'] = 'Administration'; + $this->goToTarget('basecontent/'); + } + } + + function protocol($type) { + $this->layout = 'admin'; + $this->check_login('basecontent/protocol/'.$type); + + $logfile = "Auflistung der Benutzeraktionen\r\n\r\n"; + + switch ($type) { + + case 'screen': + $array = $this->datamodel->retrieve('basecontent', '*', '', 'id DESC', '30'); + foreach ( $array as $row ) { + $logfile .= $row['id'].": ".$row['name']." (".$row['ip'].") - ".$row['date']." - ".$row['action']."\r\n"; + } + + $this->data['logfile'] = $logfile; + $this->data['title'] = "Logfile ausgeben"; + $this->logaction('Logfile am Bildschirm ausgegeben. (30 Aktionen)'); + $this->layout = 'viewprotocol'; + break; + + case 'textfile': + $array = $this->datamodel->retrieve('basecontent', '*', '', 'id ASC'); + foreach ( $array as $row ) { + $logfile .= $row['id'].": ".$row['name']." (".$row['ip'].") - ".$row['date']." - ".$row['action']."\r\n"; + } + $logfile .= "\r\nEnde der Logfileausgabe"; + $logfile = html_entity_decode($logfile); + + header("Content-length: ".strlen($logfile)); + header("Content-type: text/plain"); + header("Content-Disposition: attachment; filename=aktionen.log"); + echo $logfile; + + $this->flash('Logfile als Datei heruntergeladen'); + exit(); + break; + } + } + + function support() { + $this->check_login('basecontent/support'); + // Eine mail an info@2erlei mit "Seitenname, IP, Uhrzeit, username, ggf. Protokoll" abschicken + + $user = $this->datamodel->retrieve('user', 'email', "name = '".$_SESSION['username']."'", '', '1'); + $result = $this->datamodel->retrieve(ADMINMODULE.'_options', '*', "optionname='SEITENTITEL'"); + $sitetitle = $result['value']; + + $array = $this->datamodel->retrieve('basecontent', '*', '', 'id DESC', '30'); + foreach ( $array as $row ) { + $logfile .= $row['id'].": ".$row['name']." (".$row['ip'].") - ".$row['date']." - ".$row['action']."\r\n"; + } + unset($array); + + $config['mailreceipient'] = 'info@2erlei.de'; + $config['mailtopic'] = '['.$sitetitle.'] Supportanfrage'; + $config['mailfrom'] = 'supportbutton@'.$_SERVER['HTTP_HOST']; + $config['replyto'] = $user['email']; + $content = 'Es wurde eine Supportanfrage abgegeben.'."\n"; + $content .= "\n".'Seitentitel:'."\t". $sitetitle; + $content .= "\n".'IP:' . "\t\t" . $_SESSION['IP']; + $content .= "\n".'Uhrzeit:' . "\t" . date('Y-m-d H:i:s', mktime() ); + $content .= "\n".'Benutzer:' . "\t". $_SESSION['username']; + $content .= "\n".'Protokoll:'."\n". $logfile; + $content .= "\n\n".'Ende der Supportanfrage'; + $content .= "\n-- \nbaseContent"; + + if ( mail($config['mailreceipient'], $config['mailtopic'], $content, "From: {$config['mailfrom']}\r\n"."Reply-To: {$config['replyto']}") ) { + $notify['mailed'] = TRUE; + $notify['status'] = "2erlei wurde per e-mail über Ihren Supportwunsch informiert."; + } else { + $notify['mailed'] = FALSE; + $notify['status'] = "

Fehler

Auf diesem Server ist kein Mailversand möglich. Bitte richten Sie Ihre Supportanfrage telefonisch an 2erlei. "; + } + $this->flash($notify['status']); + + $this->goToTarget('basecontent/'); + } + + function webframe($page='') { + $this->layout = 'default'; + $this->goToTarget($page); + /* + $this->data['title'] = 'Webseiten-Ansicht'; + if ( $page == 'top' ) { + echo file_get_contents($this->modulepath . 'basecontent/de/frame_top.php'); + } + */ + } + + function common() { + return $this->factory->get_helper('bereiche'); + } +} +?> diff --git a/app/modules/basecontent/help.xml b/app/modules/basecontent/help.xml new file mode 100644 index 0000000..723f200 --- /dev/null +++ b/app/modules/basecontent/help.xml @@ -0,0 +1,40 @@ + + + +

hallo

+ + + +

Hier werden die Grundeinstellungen für Ihren Internetauftritt vorgenommen.

+ +

Wählen Sie einen Reiter für die Einstellung, die Sie vornehmen möchten.

+ +

OPTIONEN EINSTELLEN

+

Seitentitel
+ Der Seitentitel erstreckt sich durch Ihren kompletten Internetauftritt und ist an mehreren Stellen, wie z.B. oben in der Fensterleiste im Browser, zu sehen.

+
+
+ +

Alle Änderungen und Aktionen, die im baseContent vorgenommen werden, sind in diesem Protokoll zusammengefasst und können jederzeit eingesehen werden.

+

Sie können genau verfolgen, wer, was und wann gemacht hat. Neben dem Benutzernamen wird die Aktion, das Datum und die Uhrzeit protokolliert.

+
+ + +

Willkommen im Projectmanager der 2erlei-GbR!

*(ftp): Mit Klick auf dem Link gelangt Ihr über euren Browser direkt zu dem Verzeichniss auf dem "Friedrich".
Wenn euer Browser das nicht unterstützen sollte, stehen hier die URL und Zugangsdaten:

+
    +
  • URL: ftp://nd.2erlei.de
  • +
  • BN: "Projekt- oder Firmenname"
  • +
  • PW: 2erleiProjekt
  • +
+


Mindmap: Bitte stehts die aktuelle Mindmap herunterladen, editieren und anschließend über ein FTP Programm wieder hochladen!
Es besteht die Gefahr des Datenverlustes!!! +

+ +
+ + + + diff --git a/app/modules/basecontent/layouts/admin.php b/app/modules/basecontent/layouts/admin.php new file mode 100644 index 0000000..bf4a76a --- /dev/null +++ b/app/modules/basecontent/layouts/admin.php @@ -0,0 +1,61 @@ +'."\n"; ?> + + + + <?php echo $this->get_field('title') ?> - <?php $this->get_siteTitle() ?> +get_element('admin_head'); ?> + + +
+ +
+

baseContent

+

» get_username(); ?> Logout

+ +
+ get_element('bc_nav', array('section'=>'localarea')); ?> +
+ + + +

get_siteTitle(); ?>

+ get_breadcrumbs($this->cap, $this->get_field('title')); ?> +
+ + + +
+get_sub_view(); ?> + +
+

baseContent info

+ get_element('bc_info', array('cap'=>$this->cap, 'flash'=>$this->render_flash(), 'model'=>$this) ); ?> +
+
+ +
+

   

+ +
+ +
+ + diff --git a/app/modules/basecontent/layouts/loginout.php b/app/modules/basecontent/layouts/loginout.php new file mode 100644 index 0000000..5b851f9 --- /dev/null +++ b/app/modules/basecontent/layouts/loginout.php @@ -0,0 +1,54 @@ + + + + + <?php echo $this->get_field('title') ?> - <?php $this->get_siteTitle() ?> +get_element('admin_head'); ?> + + + + + diff --git a/app/modules/basecontent/layouts/viewprotocol.php b/app/modules/basecontent/layouts/viewprotocol.php new file mode 100644 index 0000000..936a474 --- /dev/null +++ b/app/modules/basecontent/layouts/viewprotocol.php @@ -0,0 +1,54 @@ +'."\n"; ?> + + + + <?php echo $this->get_field('title') ?> - <?php $this->get_siteTitle() ?> +get_element('admin_head'); ?> + + +
+ +
+

baseContent

+

» get_username(); ?> Logout

+ +
+ get_element('bc_nav', array('section'=>'basecontent')); ?> +
+ + + +

get_siteTitle(); ?>

+
+ +
+ +

Protokoll

+
+get_field('logfile'); ?>
+		
+

Ende der Logfileausgabe
(Es wurden nur die 30 letzten Aktionen angezeigt.)

+ +
+ +
+

   

+ +
+ +
+ + diff --git a/app/modules/basecontent/layouts/webframe.php b/app/modules/basecontent/layouts/webframe.php new file mode 100644 index 0000000..f6f615f --- /dev/null +++ b/app/modules/basecontent/layouts/webframe.php @@ -0,0 +1,19 @@ +'."\n"; ?> + + + + <?php echo $this->get_field('title') ?> - <?php $this->get_siteTitle() ?> + + + + + + + diff --git a/app/modules/basecontent/model.php b/app/modules/basecontent/model.php new file mode 100644 index 0000000..2313a53 --- /dev/null +++ b/app/modules/basecontent/model.php @@ -0,0 +1,61 @@ +login_right( addslashes($fl['username']), addslashes($fl['password']) ) + AND !isset($_SESSION['username']) + ) { + return TRUE; + } elseif ( $this->login_right( addslashes($fl['username']), addslashes($fl['password']) ) == 0) { + return FALSE; + } + + if($_SESSION['IP'] != $_SERVER['REMOTE_ADDR']) + die('Falsche Sessiondaten, bitte erneut einloggen.'); + } + + function login_right($user, $pass) { + $result = $this->datamodel->retrieve('user','COUNT(*) as anzahl',"name = '".$user."' AND password = MD5('".$pass."')"); + + return $result['anzahl']; + } + + function get_trashcan_data($modules) { + $trashcan_data = array(); + + foreach( $modules as $name => $module ) { + $controller = str_replace('_LANG', '', $module); + $controller = str_replace('_', '', $controller); + $module = str_replace('LANG', LANG, $module); + $sql = 'SELECT * FROM fl_'.$module.' WHERE status = 2;'; + + $data[$module] = $this->datamodel->_query_db($sql); + if ( isset($data[$module]['id']) ) { + $tmp = $data[$module]; + unset($data); + + $data[$module][] = $tmp; + } + + $data[$module]['title'] = $name; + $data[$module]['controller'] = $controller; + + if ( count( $data[$module] ) <= 2 ) continue; + + $trashcan_data += $data; + } + + return $trashcan_data; + } +} +?> diff --git a/app/modules/basecontent/modul.php b/app/modules/basecontent/modul.php new file mode 100644 index 0000000..31cbefa --- /dev/null +++ b/app/modules/basecontent/modul.php @@ -0,0 +1,67 @@ + + * @version 0.1.7 + * @license All Rights Reserved + */ + +/** + * Modul zentral registrieren + */ +$installed_modules[] = 'basecontent'; + +/** + * Allgemeines zum Modul + */ +class basecontent_modul extends fl_modul { + function get_options($modules) { + echo '
allgemeine Optionen +

+

+

'.$this->get_dropdown('adminhelp', 'sichtbar=anzeigen,unsichtbar=verstecken').'

+
'."\n"; + } + + function get_dropdown($field, $options) { + $options = explode(',', $options); + $aktuell = $this->_get_option('basecontent', $field); + $html = ''; + + $html .= "\n\t\t\t".''; + + return $html; + } + + function get_name() { + return FALSE; + } + + function get_starttext() { + echo ''; + } + + function prepare() { + $this->factory->get_helper('minixml'); + } +} +?> diff --git a/app/modules/basecontent/view.php b/app/modules/basecontent/view.php new file mode 100644 index 0000000..137f528 --- /dev/null +++ b/app/modules/basecontent/view.php @@ -0,0 +1,56 @@ +data['from']; + } + + function get_subtitle() { + echo $this->get_field('subtitle'); + } + + function get_content() { + echo $this->get_field('content'); + } + + function get_html_content() { + $textile = new Textile(); + $html = $textile->process( $this->data['content'] ); + echo $html; + } + + function get_all_options() { + $federleicht = get_fl(); + $modules = &$federleicht->modules; + + foreach( $modules as $module) { + require_once($this->modulepath.$module.'/modul.php'); + $temp_module_object = new $module($federleicht); + $temp_module_object->get_options($modules); + unset($temp_module_object); + } + } + + function get_all_starttexts() { + $federleicht = get_fl(); + $modules = &$federleicht->modules; + + foreach( $modules as $module) { + require_once($this->modulepath.$module.'/modul.php'); + $temp_module_object = new $module($federleicht); + $temp_module_object->get_starttext(); + unset($temp_module_object); + } + } +} +?> diff --git a/app/modules/basecontent/views/frame_top.php b/app/modules/basecontent/views/frame_top.php new file mode 100644 index 0000000..473bb1a --- /dev/null +++ b/app/modules/basecontent/views/frame_top.php @@ -0,0 +1,23 @@ + + + <?php echo $this->get_field('title') ?> - <?php $this->get_siteTitle() ?> +get_element('admin_head'); ?> + + + +
+ +
+

baseContent

+

» Logout

+ +
+ get_element('bc_nav'); ?> +
+
+ + + diff --git a/app/modules/basecontent/views/login.php b/app/modules/basecontent/views/login.php new file mode 100644 index 0000000..2d4d0c4 --- /dev/null +++ b/app/modules/basecontent/views/login.php @@ -0,0 +1,27 @@ + +

get_field('title'); ?>

+
+

 

+
 
+ +

+

+
 
+

Einloggen

+ +
 
+
+
+ + diff --git a/app/modules/basecontent/views/logout.php b/app/modules/basecontent/views/logout.php new file mode 100644 index 0000000..225af82 --- /dev/null +++ b/app/modules/basecontent/views/logout.php @@ -0,0 +1,17 @@ + +

Logout erfolgreich

+

 

+
 
+

Der Logoutvorgang wurde erfolgreich abgeschlossen.

+

Aus Sicherheitsgründen kann es empfehlenswert sein, dieses Browserfenster zu schliessen. Dies gilt insbesonderen, wenn Sie diese Seite an einem öffentlichen Computer (z. B. Internetcafé) genutzt haben.

+

Zur Startseite

+
 
+
 
+
\ No newline at end of file diff --git a/app/modules/basecontent/views/notallowed.php b/app/modules/basecontent/views/notallowed.php new file mode 100644 index 0000000..a282e33 --- /dev/null +++ b/app/modules/basecontent/views/notallowed.php @@ -0,0 +1,9 @@ + +

Fehlende Berechtigung

+oben('optionen', '   '); ?> +

Leider haben Sie keine ausreichende Rechte, um auf die gewünschte Funktion zugreifen zu können.

+

Bitte wenden Sie sich an einen Administrator, um weitere Informationen zu erhalten.

+buttons('abbrechen'); ?> +unten(); ?> diff --git a/app/modules/basecontent/views/options.php b/app/modules/basecontent/views/options.php new file mode 100644 index 0000000..5591e61 --- /dev/null +++ b/app/modules/basecontent/views/options.php @@ -0,0 +1,10 @@ + +

Einstellungen bearbeiten

+
+oben('optionen', 'Optionen einstellen'); ?> + get_all_options(); ?> +buttons('speichern'); ?> +unten(); ?> +
diff --git a/app/modules/basecontent/views/protocol.php b/app/modules/basecontent/views/protocol.php new file mode 100644 index 0000000..4be2b51 --- /dev/null +++ b/app/modules/basecontent/views/protocol.php @@ -0,0 +1,21 @@ + +

Protokoll (Ãœbersicht)

+

 

+
 
+

Sie können das Protokoll

+ +


Die Textdatei können Sie in einem beliebigen Texteditor öffnen.

+
 
+
 
+
+ diff --git a/app/modules/basecontent/views/show.php b/app/modules/basecontent/views/show.php new file mode 100644 index 0000000..80c26fa --- /dev/null +++ b/app/modules/basecontent/views/show.php @@ -0,0 +1,60 @@ +functions->needs('bereiche'); $bereiche = new bereiche(); ?> + + +

wichtigsten Links der 2erlei-GbR

+ +oben('hauptbereich', 'allgemeine Links'); ?> + + + +buttons('weiter:kunden'); ?> +unten(); ?> + +oben('kunden', 'Links von Kunden und Projekten'); ?> + +unterbrechung(); ?> + +unterbrechung(); ?> + + +buttons('zurueck:hauptbereich,weiter:bisher'); ?> +unten(); ?> + +oben('bisher', 'bisherige Links'); ?> + + +buttons('zurueck:kunden'); ?> +unten(); ?> + + diff --git a/app/modules/basecontent/views/trashcan.php b/app/modules/basecontent/views/trashcan.php new file mode 100644 index 0000000..3a82735 --- /dev/null +++ b/app/modules/basecontent/views/trashcan.php @@ -0,0 +1,46 @@ +

Papierkorb (Ãœbersicht)

+ +data; +unset($moduldaten['title']); +unset($moduldaten['controller']); + +$this->functions->needs('bereiche'); +$bereiche = new bereiche(2); + +if ( count($moduldaten) == 0 ) { + $bereiche->oben('modulliste', 'Papierkorb'); +?> +

Hier werden die gelöschten Datensätze aufgelistet.

+

Derzeit sind keine Datensätze als gelöscht markiert.

+buttons(); + $bereiche->unten(); +} else { + + foreach( $moduldaten as $modul ) { + $bereiche->oben("modul_".strtolower($modul['controller']), $modul['title']); ?> +
    + +
  • + +
+ +buttons(); + $bereiche->unten(); + } // outer endforeach +} +?> diff --git a/app/modules/coding/controller.php b/app/modules/coding/controller.php new file mode 100644 index 0000000..624cf6c --- /dev/null +++ b/app/modules/coding/controller.php @@ -0,0 +1,33 @@ +data['title'] = 'baseContent'; + } + + function html() { + $this->data['title'] = 'HTML/CSS'; + } + + function mysql() { + $this->data['title'] = 'MySQL-Datenbanken'; + } + + function common() { + $bild = ( $this->cap['action'] == 'defaultAction' )? $this->defaultAction: $this->cap['action']; + $this->data['kopfbild'] = $bild; + return TRUE; + } +} +?> diff --git a/app/modules/coding/help.xml b/app/modules/coding/help.xml new file mode 100644 index 0000000..defb4c8 --- /dev/null +++ b/app/modules/coding/help.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/modules/coding/layouts/default.php b/app/modules/coding/layouts/default.php new file mode 100644 index 0000000..071c7bd --- /dev/null +++ b/app/modules/coding/layouts/default.php @@ -0,0 +1,36 @@ + + + + + 2erlei Medienagentur +get_element('header'); ?> + + +
+
+

2erlei Medienagentur

+ +
+ get_element('kundennavi'); ?> + +
+ + + + +
+ +
+get_sub_view(); ?> +
+ +
+ get_element('unten'); ?> + +
+
get_element('google_analytics'); ?> + + diff --git a/app/modules/coding/model.php b/app/modules/coding/model.php new file mode 100644 index 0000000..28f97af --- /dev/null +++ b/app/modules/coding/model.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/coding/modul.php b/app/modules/coding/modul.php new file mode 100644 index 0000000..1f5bf27 --- /dev/null +++ b/app/modules/coding/modul.php @@ -0,0 +1,17 @@ + + * @version 0.1.7 + * @license All Rights Reserved + */ + +/** + * Allgemeines zum Modul + */ +class coding_modul extends fl_modul { +} +?> diff --git a/app/modules/coding/view.php b/app/modules/coding/view.php new file mode 100644 index 0000000..e97b190 --- /dev/null +++ b/app/modules/coding/view.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/coding/views/basecontent.php b/app/modules/coding/views/basecontent.php new file mode 100644 index 0000000..7e08704 --- /dev/null +++ b/app/modules/coding/views/basecontent.php @@ -0,0 +1,22 @@ + + +
+

baseContent

+

Unser baseContent bietet ihnen eine gute und effiziente Basis für ihre Präsenz im Internet.

+

Sie baut auf dem Prinzip eines einfach zu handhabenen Content Management Systems, womit sie direkt Einfluss auf die Gestaltung Ihres Internetauftritts nehmen können.

+

baseContent ist selbstadministrierbar ohne das sie Programmierkenntnisse oder weitere Software, als Ihren gewöhnlichen Internetbrowser, benötigen.

+

Selbstadministration bedeutet, dass sie selbstständig Texte und Bilder einfügen können, die automatisch in die Webseite eingebunden werden.

+

Sie konzentrieren sich auf ihre Inhalte und 2erlei macht den Rest.

+
+ +
+

Hier Das Passende

+

Webdesign

+

HTML

+

Hosting

+
+ diff --git a/app/modules/coding/views/hosting.php b/app/modules/coding/views/hosting.php new file mode 100644 index 0000000..f038e87 --- /dev/null +++ b/app/modules/coding/views/hosting.php @@ -0,0 +1,39 @@ + +

Hosting

+

Ihr persönliches CMS für Ihr individuelles Unternehmen

+ + + +
+ baseContent Teaser +
+ +
+

Hosting

+ +

Wir hosten und betreuen Ihre Internetseite

+ +

Unsere Server werden von unseren kompetenten Administratoren rund um die Uhr überwacht.

+ +

Bei der Technik arbeiten wir mit einer der größten und renommiertesten Hostinganbietern, der 1&1 Internet AG zusammen.

+ +

Ihr Internetauftritt ist bei uns in sicheren Händen und wird von uns mit größtmöglichen Sicherheitsstandards vor Missbrauch geschützt.

+ +

Sie können sich in Ihrem Unternehmen auf das wesentliche konzentrieren, ohne viele Verträge abzuschließen und 2erlei macht den Rest.

+
+ +
+

Hier Das Passende

+

baseContent

+

Webdesign

+

HTML

+ +
diff --git a/app/modules/coding/views/html.php b/app/modules/coding/views/html.php new file mode 100644 index 0000000..d9c9be6 --- /dev/null +++ b/app/modules/coding/views/html.php @@ -0,0 +1,24 @@ + + +
+

statisches HTML

+

Die Struktur und Aufbau einer Internetseite optmiert für alle gängigen Browser

+

Wir setzen Ihr Design in eine "lebendige" Internetseite um.

+

Die Programmierung erfolgt nach den neusten Webstandards und unter Berücksichtigung der Barrierefreiheit.

+

Die Inhalte werden mit HTML strukturiert.
Die Anordnung und Darstellung wird über ein CSS (cascading stylesheet) gesteuert.

+

Die Inhalte werden mit XHTML für die Ausgabe strukturiert. Die Anordnung und Darstellung wird +über ein CSS (cascading stylesheet) gesteuert. Die Daten liegen in einer Datenbank. Die in +der Datenbank befindlichen Daten, werden mit Hilfe von PHP verarbeitet und in ein XHTML- +Format konvertiert.

+
+ +
+

Hier Das Passende

+

baseContent

+

Webdesign

+

Hosting

+
diff --git a/app/modules/coding/views/mysql.php b/app/modules/coding/views/mysql.php new file mode 100644 index 0000000..903bc4c --- /dev/null +++ b/app/modules/coding/views/mysql.php @@ -0,0 +1,25 @@ + + +
+

MySQL-Datenbanken

+

Die Inhalte sicher und getrennt von der Struktur in einer Datenbank.

+ +

Ihre Inhalte wie Text oder Bilder können getrennt vom Programmcode in einer Datenbank gespeichert und verwaltet werden.
Damit Ihre Inhalte geschützt und übersichtlich verwaltet werden.

+ +

Auch erst mit einer Datenbank sind vernünfitge Volltextsuchen auf der Internetseite möglich.

+ +

Die Daten bzw. Inhalte werden getrennt von dem Programmcode und der Darstellung in +einer geschützten MySQL-Datenbank gespeichert. Über die Administrationsoberfläche (CMS) +können sie bearbeitet und organisiert werden.

+
+ +
+

Hier Das Passende

+

baseContent

+

HTML

+

Webdesign

+
diff --git a/app/modules/common/layouts/default.php b/app/modules/common/layouts/default.php new file mode 100644 index 0000000..86aa208 --- /dev/null +++ b/app/modules/common/layouts/default.php @@ -0,0 +1,36 @@ + + + + + 2erlei +get_element('header'); ?> + + +
+
+

2erlei Medienagentur

+ +
+ get_element('kundennavi'); ?> + +
+ + + + +
+ +
+get_sub_view(); ?> +
+ +
+ get_element('unten'); ?> + +
+
+ + diff --git a/app/modules/design/controller.php b/app/modules/design/controller.php new file mode 100644 index 0000000..542dce0 --- /dev/null +++ b/app/modules/design/controller.php @@ -0,0 +1,33 @@ +data['title'] = 'Webdesign'; + } + + function druck() { + $this->data['title'] = 'Drucksachen'; + } + + function corporate() { + $this->data['title'] = 'Corporate Identity'; + } + + function common() { + $bild = ( $this->cap['action'] == 'defaultAction' )? $this->defaultAction: $this->cap['action']; + $this->data['kopfbild'] = $bild; + return TRUE; + } +} +?> diff --git a/app/modules/design/help.xml b/app/modules/design/help.xml new file mode 100644 index 0000000..eb751c1 --- /dev/null +++ b/app/modules/design/help.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/modules/design/layouts/default.php b/app/modules/design/layouts/default.php new file mode 100644 index 0000000..5564a9d --- /dev/null +++ b/app/modules/design/layouts/default.php @@ -0,0 +1,37 @@ + + + + + 2erlei Medienagentur +get_element('header'); ?> + + +
+
+

2erlei Medienagentur

+ +
+ get_element('kundennavi'); ?> + +
+ + + + +
+ +
+get_sub_view(); ?> +
+ +
+ get_element('unten'); ?> + +
+
get_element('google_analytics'); ?> +get_element('lightbox'); ?> + + diff --git a/app/modules/design/model.php b/app/modules/design/model.php new file mode 100644 index 0000000..f9a11d2 --- /dev/null +++ b/app/modules/design/model.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/design/modul.php b/app/modules/design/modul.php new file mode 100644 index 0000000..e0bc454 --- /dev/null +++ b/app/modules/design/modul.php @@ -0,0 +1,17 @@ + + * @version 0.1.7 + * @license All Rights Reserved + */ + +/** + * Allgemeines zum Modul + */ +class design_modul extends fl_modul { +} +?> diff --git a/app/modules/design/view.php b/app/modules/design/view.php new file mode 100644 index 0000000..2833587 --- /dev/null +++ b/app/modules/design/view.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/design/views/corporate.php b/app/modules/design/views/corporate.php new file mode 100644 index 0000000..6891957 --- /dev/null +++ b/app/modules/design/views/corporate.php @@ -0,0 +1 @@ +

Corporate Identity

Geben Sie Ihren Kunden Orientierung und Sicherheit mit einer unverwechselbaren Indentität.

Ausgangspunkt

Für ein Unternehmen wird es immer notwendiger, aufgrund der Unübersichtlichkeit der Leistungsangebote auf dem Markt, sich von Ihrer Konkurrenz abzuheben.

Hersteller müssen durch die immer größer werdende Produktvielfalt darum kämpfen, in das Sortiment des Handels aufgenommen zu werden. Vorteile hat der, der ein gutes und unverwechselbares Image genießt.

Entwicklung

Die Entwicklung einer Corporate Identity ist kompliziert und stellt hohe Anforderungen eine vernetzte Struktur in einem übersichtlichen Design zu vereinen. Daher greifen viele Unternehmen anfangs Einzelaspekte auf, vor allem das Design für die Kommunikation. Dies kann aber nicht dem strategischen Aspekt gerecht werden, zu einem ganzeinheitlichen Design zu gelangen. Daher muss man genau die Unternehmensstruktur, unter Berücksichtigung der angestrebten Ziele, analysieren. Aufgrund der Analyse lässt sich das Unternehmen, mit den zur Verfügung stehenden Instrumenten, in ein einheitliches, sinngemäßes und wieder erkennbares Design zusammenfassen.

Die Planung für den späteren Kostenaufwand für die Produktion ist von entscheidender Bedeutung, damit auch das einheitliche Design bewart bleibt.

Die Hausfarbe

Die Hausfarbe ist eines der wichtigsten Instrumente, weil es ein unmittelbar einprägendes Erkennungs- und Unterscheidungsmerkmal für Unternehmen darstellt. Wir stehen Ihnen beratend zur Seite, dass die Farbe auch ohne hohen Kostenaufwand überall einsetzbar wird. Gerade im Druckbereich wird es zu einem wichtigen Thema, in wie weit sich diese Farbe und auf welchen Untergrund drucken lässt.

Logo

Von einem Unternehmenszeichen, auch Logo genannt, werden viele Eigenschaften erwartet:

- Aufmerksamkeit, Signalwirkung
- langlebig und zeitlos
- ästhetisch und eigenständige Aussage
- Integration auf vielfältigsten Vorlagen
- Informations- und Erinnerungswert

Die Hausfarbe sollte in dem Logo auftauchen und prägend wirken.

Schriften

Innovative Firmen zeigen ebenfalls Fortschritt, wenn sie keine klassisch konservativen Schriften verwenden. Von der Schrift muss zu erwarten sein, dass sie möglichst zeitlos ist und keinem aktuellen Modetrend folgt.

Gestaltungsraster

Der Empfänger registriert als erstes das Objekt als ganzes. Die Details untersteichen den individuellen Karakter des Unternehmens. Das definierte Raster gewährleistet ein gleichbleibenes Design, das auf keinen Fall gebrochen werden sollte. Da kommen wir wieder zu dem Thema, dass möglichst alle Aspekte in der Analyse berücksichtigt werden sollten.

Ergebnis

Diese Instrumente müssen nach dem strategischen Ziel entsprechend eingesetzt werden.

Die Leitidee nennt den Sinn des Unternehmens und vermittelt eine Vision, wie es aktuelle und künftige Probleme lösen oder dazu beitragen will.

Die Leitsätze sind Kernaussagen bestimmen das Verhältnis des Unternehmens zu zentralen Bezugsgruppen wie Mitarbeiter, Kunden, Aktionäre, Medien. Die Leitsätze formulieren die spezifische Kompetenz des Unternehmens, seine Leistungsfähigkeit und die Wettbewerbsvorteile.

Das Motto

Leitidee und Leitsätze sind meist zu lang, um sie sich merken zu können. Ein Motto bringt daher das Leitbild auf den Punkt: Es ist kurz, prägnant und leicht zu merken.

Das Motto fasst alles in einem kurzen, prägnanten Slogan zusammen.

Hier Das Passende

Drucksachen

Fotografie

Webdesign

\ No newline at end of file diff --git a/app/modules/design/views/druck.php b/app/modules/design/views/druck.php new file mode 100644 index 0000000..63ce692 --- /dev/null +++ b/app/modules/design/views/druck.php @@ -0,0 +1,21 @@ + + +
+

Drucksachen

+ +

Design ist der Prozess

+

Die Aufgaben eines Designs können verschiedener Ziele unterliegen. Design kann Emotionen hervorrufen, komplexe Systeme erklärend unterstützen und viel mehr.

+

Design bedeutet mehr als nur Formgebung und Styling: Gutes Design ist ein komplexer Prozess, in dem unterschiedliche und oft widersprüchliche Anforderungen erfüllt werden müssen, damit Objekte in der gewünschten Art und Weise funktionieren.

+ +

Wir gestalten Ihnen alles mit unserer geballten Kompetenz und Leidenschaft, von Produktvorstellung über Bewerbungsmappe, von der Internetseite bis hin zu einer komplexen Werbekampagne.

+
+ +
+

Hier Das Passende

+

Corporate Identity

+

Fotografie

+
diff --git a/app/modules/design/views/photo.php b/app/modules/design/views/photo.php new file mode 100644 index 0000000..7d42a64 --- /dev/null +++ b/app/modules/design/views/photo.php @@ -0,0 +1,35 @@ + +

Fotografie

+

Die Form folgt der Funktion, unsere Gestaltung ihren Bedürfnissen

+ + + +
+ baseContent Teaser +
+ +
+

Fotografie

+ +

Unser Netzwerk von Fotografen runden Ihr Produkt ab.

+ +

Wir bieten nicht nur einen Textcontent für Ihre Webseite zur Erstellen, sondern auch den bildlichen Content zu liefern.

+

Ob Sie schon vorhandene Fotos optimiert haben möchten oder sogar noch gar keine besitzen, da kommen wir ins Spiel. Wir optimieren Ihre Bilder oder wir schicken einer unser kompetenten Fotografen bei Ihnen vorbei.

+ +

Komplette Internetseite aus einer Hand.

+
+ +
+

Hier Das Passende

+

Webdesign

+

baseContent

+

Drucksachen

+
diff --git a/app/modules/design/views/web.php b/app/modules/design/views/web.php new file mode 100644 index 0000000..ac571c1 --- /dev/null +++ b/app/modules/design/views/web.php @@ -0,0 +1,21 @@ + + +
+

Webdesign

+

Heben Sie sich mit einem individuellen Design von Ihrer Konkurrenz ab.

+

Wir gestalten Ihnen eine individuelle Webseite, die neben dem Design vor allem eine größtmögliche Nutzerfreundlichkeit umfasst.

+

Aufbau und Navigation werden in einer übersichtlichen Struktur angeordnet.

+

Wir sind bestrebt, ein Design für Sie zu entwerfen, das alle diese Aspekte umfasst und zu einer vernünftigen Usability führt. Das Ihre User schnell und direkt informiert werden, was Sie tun und was Sie anbieten.

+

Die Wirtschaftlichkeit einer Seite kann von entscheidender Bedeutung sein, um der Konkurrenz einen Schritt voraus zu sein. Zwischen potentieller Kunde und Unternehmen steht in vielen Fällen die Internetseite.

+
+ +
+

Hier Das Passende

+

baseContent

+

HTML

+

Fotografie

+
diff --git a/app/modules/pages/controller.php b/app/modules/pages/controller.php new file mode 100644 index 0000000..0009221 --- /dev/null +++ b/app/modules/pages/controller.php @@ -0,0 +1,74 @@ +data['title'] = 'Willkommen'; + } + + function contact($action) { + $this->data['title'] = 'Kontakt'; + + $val = $this->factory->get_helper('validation'); + + $val->set_rule('name', 'string'); + $val->set_msg('name', 'Bitte geben Sie Ihren Namen an.'); + + $val->set_rule('firma', '', '*'); + $val->set_msg('firma', 'Bitte geben Sie den Namen Ihrer Firma an oder lassen Sie das entsprechende Feld frei.'); + + $val->set_rule('mail', 'email'); + $val->set_msg('mail', 'Bitte geben Sie Ihre E-Mail-Adresse an.'); + + $val->set_rule('telefon', 'number', '*'); + $val->set_msg('telefon', 'Bitte geben Sie Ihre Telefonnummer an oder lassen Sie das entsprechende Feld frei.'); + + $val->set_rule('thema', 'string'); + $val->set_msg('thema', 'Bitte wählen Sie ein Thema aus.'); + + if ( $action == 'send' ) { + $data = ( isset($_POST['fl']) )? $_POST['fl']: $this->goToTarget('pages/contact/'); + $errors = $val->validate_form($data); + + if ( count($errors) == 0 ) { + $sent = $this->model->send_contact($data); + $msg = ( $sent === TRUE )? + 'Danke! Ihre Anfrage wurde an uns abgeschickt.': + '[Systemfehler] e-mail wurde nicht verschickt.
' . $sent; + $type = ( $sent === TRUE )? + 'okay': + 'error'; + $this->flash($msg, $type); + #$this->goToTarget('pages/thankyou'); + } else { + $this->data += $data; + $msg = implode('
', $errors ); + $this->flash($msg, 'error'); + } + } + + $this->data['system']['validator'] = $val; + } + + function thankyou() { + $this->data['title'] = 'Vielen Dank!'; + } + + function impressum() { + $this->data['title'] = 'Impressum'; + } + + function sitemap() { + $this->data['title'] = 'Sitemap'; + } +} +?> diff --git a/app/modules/pages/help.xml b/app/modules/pages/help.xml new file mode 100644 index 0000000..f03b7f9 --- /dev/null +++ b/app/modules/pages/help.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/modules/pages/layouts/default.php b/app/modules/pages/layouts/default.php new file mode 100644 index 0000000..8b6b1dc --- /dev/null +++ b/app/modules/pages/layouts/default.php @@ -0,0 +1,35 @@ + + + + + 2erlei Medienagentur +get_element('header'); ?> + + +
+
+

2erlei Medienagentur

+ +
+ get_element('kundennavi'); ?> + +
+ + + + +
+ +
+get_sub_view(); ?> +
+ +
+ get_element('unten'); ?> + +
+
get_element('google_analytics'); ?> + diff --git a/app/modules/pages/model.php b/app/modules/pages/model.php new file mode 100644 index 0000000..0c5c183 --- /dev/null +++ b/app/modules/pages/model.php @@ -0,0 +1,39 @@ +functions->needs('mail'); + $m = new e_mail(); + + $to = 'info@2erlei.de'; + $from = 'kontaktformular@2erlei.de'; + $topic = '[2erlei] Kontaktformular'; + $template = file_get_contents( ABSPATH . 'app/modules/pages/views/contact.tpl'); + $data['time'] = date('d.m.Y \u\m H:i', mktime()); + + $text = $m->parse_template($template, $data); + + $m->set_config($to, $from, $topic); + $m->set_text($text); + $m->compose_message(); + + $send_contact = $m->send_mail(); + if (!$send_contact) $send_contact = $m->get_error(); + + return $send_contact; + } +} +?> diff --git a/app/modules/pages/modul.php b/app/modules/pages/modul.php new file mode 100644 index 0000000..1bcd465 --- /dev/null +++ b/app/modules/pages/modul.php @@ -0,0 +1,17 @@ + + * @version 0.1.7 + * @license All Rights Reserved + */ + +/** + * Allgemeines zum Modul + */ +class pages_modul extends fl_modul { +} +?> diff --git a/app/modules/pages/view.php b/app/modules/pages/view.php new file mode 100644 index 0000000..5131657 --- /dev/null +++ b/app/modules/pages/view.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/pages/views/contact.php b/app/modules/pages/views/contact.php new file mode 100644 index 0000000..f8ed69c --- /dev/null +++ b/app/modules/pages/views/contact.php @@ -0,0 +1,19 @@ + +data['system']['validator']->get_js(); ?> +factory->get_helper('html'); $html->set_data($this->data); ?> + + + +
+

Kontaktformular

+
render_flash(); ?>
+
+

get_input('name', 'Ihr Name*:'); ?>

+

get_input('firma', 'Firma:'); ?>

+

get_input('mail', 'Ihre E-Mail*:'); ?>

+

get_input('telefon', 'Rückrufnummer:'); ?>

+

get_dropdown('thema', '=Bitte Thema auswählen,Angebot=Anfrage für ein Angebot,Design=Frage zu Design,Technik=Frage zu Code&Technik,Jobs=Jobangebote,Allgemein=Allgemeine Anfrage'); ?>

+

get_textarea('message', 'Ihr Anliegen:'); ?>

+

+
+
diff --git a/app/modules/pages/views/contact.tpl b/app/modules/pages/views/contact.tpl new file mode 100644 index 0000000..711ef7f --- /dev/null +++ b/app/modules/pages/views/contact.tpl @@ -0,0 +1,9 @@ +Name: {NAME} +Firma: {FIRMA} +e-mail: {MAIL} +Telefon: {TELEFON} + +Thema: {THEMA} +{MESSAGE} + +Das Kontaktformular wurde am {TIME} abgeschickt. diff --git a/app/modules/pages/views/impressum.php b/app/modules/pages/views/impressum.php new file mode 100644 index 0000000..070c4c6 --- /dev/null +++ b/app/modules/pages/views/impressum.php @@ -0,0 +1,26 @@ + + +
+

Die Unternehmung

+ +

2erlei - Konzeption und Gestaltung

+ +

Admiralstr. 20
D-10999 Berlin
T+ 49 (0)176 / 25 33 10 83

+

*Norman Treiber
 Mediengestalter digital & print

+

*Bastian Menningen
 Administration und Projektleitung

+


2erlei - Konzeption und Gestaltung Berlin 2005-2012

+ + get_element('haftungsausschluss'); ?> + +
+ + + + diff --git a/app/modules/pages/views/sitemap.php b/app/modules/pages/views/sitemap.php new file mode 100644 index 0000000..9da3a7c --- /dev/null +++ b/app/modules/pages/views/sitemap.php @@ -0,0 +1,50 @@ + + +
+

Sitemap

+ +
Startseite
+ +

> Startseite

+ +
Form & Farbe
+ +

> Webdesign

+ +

> Drucksachen

+ +

> Corporate Identity

+ +
Code & Technik
+ +

> baseContent

+ +

> statisches HTML

+ +

> MySQL-Datenbanken

+ +
Referenzen
+ +

> Portfolio - Webdesign

+ +

> Portfolio - Logos/ Bildmarken

+ +

> Portfolio - Drucksachen

+ +
über 2erlei
+ +

> das Unternehmen

+ +

> Partner

+ +

> Jobs

+ +
Kontakt
+ +

> Kontaktformular

+ +
Impressum
+ +

> Unternehmen & Partner

+ +
diff --git a/app/modules/pages/views/start.php b/app/modules/pages/views/start.php new file mode 100644 index 0000000..5fe09b3 --- /dev/null +++ b/app/modules/pages/views/start.php @@ -0,0 +1,18 @@ + + + +
+

Herzlich Willkommen

+ +

Die 2erlei - Konzeption und Gestaltung ist ein junges und dynamische Unternehmen.

+

Unsere qualitativ hochwertige Tätigkeit hat ihren Schwerpunkt in den Bereichen Design und Webapplikationen.

+

Die Philosophie von 2erlei gründet auf Zusammenarbeit und Vernetzung.

+

Wir sind gerade dabei unseren kompletten Internetauftritt umzustruktieren und es auf das neue Design umzustellen.

+

Gerne können Sie sich unsere Referenzen anschauen und mit uns Kontakt aufnehmen. + + +

diff --git a/app/modules/pages/views/thankyou.php b/app/modules/pages/views/thankyou.php new file mode 100644 index 0000000..abdd2fa --- /dev/null +++ b/app/modules/pages/views/thankyou.php @@ -0,0 +1,22 @@ + +

Kontakt

+

Ihr persönliches CMS für Ihr individuelles Unternehmen

+ + + +
+ +
+ +
+

Vielen Dank!

+
render_flash(); ?>
+

Wir bearbeiten eingehende Anfragen üblicherweise innerhalb von 24 Stunden.

+
+ +
+

2erlei MedienProduktion

+

baseContent

+

Unternehmen

+

Webdesign

+
diff --git a/app/modules/portfolio/controller.php b/app/modules/portfolio/controller.php new file mode 100644 index 0000000..e35a5a4 --- /dev/null +++ b/app/modules/portfolio/controller.php @@ -0,0 +1,45 @@ +data['title'] = 'Webdesign'; + $this->data['referenzen'] = $this->model->get_projects('web', $this->page); + $this->data['page_navigator'] = $this->model->get_project_pages( + 'web', 'portfolio/webdesign', $this->page + ); + } + + function logo() { + $this->data['title'] = 'Logos/ Bildmarken'; + $this->data['referenzen'] = $this->model->get_projects('logo', $this->page); + $this->data['page_navigator'] = $this->model->get_project_pages( + 'logo', 'portfolio/logo', $this->page + ); + } + + function drucksachen() { + $this->data['title'] = 'Drucksachen'; + $this->data['referenzen'] = $this->model->get_projects('print', $this->page); + $this->data['page_navigator'] = $this->model->get_project_pages( + 'print', 'portfolio/drucksachen', $this->page + ); + } + + function common($params) { + list($page) = $this->parse_params($params, 'int'); + $this->page = ( $page < 1 )? 1: $page; + $this->data['page'] = $this->page; + + return true; + } +} +?> diff --git a/app/modules/portfolio/data/webdesign.php b/app/modules/portfolio/data/webdesign.php new file mode 100644 index 0000000..9745bff --- /dev/null +++ b/app/modules/portfolio/data/webdesign.php @@ -0,0 +1,17 @@ +has_local_url() )? ' rel="lightbox"': ' target="_blank"'; + $link = ''. $this->get('title') .''; + + return $link; + } + + private function has_local_url() { + $url = $this->get('url'); + return ( $url[0] == '/' ); + } +} diff --git a/app/modules/portfolio/help.xml b/app/modules/portfolio/help.xml new file mode 100644 index 0000000..08e4592 --- /dev/null +++ b/app/modules/portfolio/help.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/modules/portfolio/layouts/default.php b/app/modules/portfolio/layouts/default.php new file mode 100644 index 0000000..11771e0 --- /dev/null +++ b/app/modules/portfolio/layouts/default.php @@ -0,0 +1,36 @@ + + + + + 2erlei Medienagentur +get_element('header'); ?> + + +
+
+

2erlei Medienagentur

+ +
+ get_element('kundennavi'); ?> + +
+ + + + +
+ +
+get_sub_view(); ?> +
+ +
+ get_element('unten'); ?> + +
+
get_element('google_analytics'); ?> + get_element('lightbox'); ?> + diff --git a/app/modules/portfolio/model.php b/app/modules/portfolio/model.php new file mode 100644 index 0000000..cd77a1c --- /dev/null +++ b/app/modules/portfolio/model.php @@ -0,0 +1,302 @@ +$method_name() + ); + + $offset = ( $this->projects_per_page * ($page-1) ); + $project_count = count($projects); + + $offset = ( $project_count < $offset )? + 0: $offset; + + $paged_projects = new LimitIterator( + $projects, $offset, $this->projects_per_page + ); + + return $paged_projects; + } + + /** + * Seitenlinks zurückgeben + * + * @param string $type + * @param string $link + * @param int $page + * @return string + */ + public function get_project_pages($type, $link, $page) { + $method_name = "get_{$type}_projects"; + $projects = $this->$method_name(); + + $previous = ( $page > 1 )? $page - 1: 1; + $last = ceil( count($projects) / $this->projects_per_page); + $next = ( $page+1 <= $last )? $page + 1: $last; + $pages = range(1, $last); + + $separator = ' | '; + + $html = ''; + $html .= ''; + + return $html; + } + + public function get_web_projects() { + $projects = array(); + + $projects[] = array( + 'title'=>'Die Deutsche Bibliothek', + 'url'=>'http://www.ddb.de', + 'assgiment'=>'Templatedesign', + 'client'=>'3-point concepts GmbH', + 'shortname'=>'ddb', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'title'=>'Dietrich Bonhoeffer', + 'url'=>'http://handschriften.staatsbibliothek-berlin.de/bonhoeffer/', + 'assgiment'=>'Bildbearbeitung', + 'client'=>'3-point concepts GmbH', + 'shortname'=>'bonhoeffer', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'title'=>'Deutscher Bibliotheksverband', + 'url'=>'http://www.bibliotheksportal.de', + 'assgiment'=>'Templatedesign/ Icongestaltung', + 'client'=>'3-point concepts GmbH', + 'shortname'=>'knb', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'title'=>'CME-Springer', + 'url'=>'http://www.cme-springer.de', + 'assgiment'=>'Screendesign', + 'client'=>'BSMO GmbH', + 'shortname'=>'cme-springer', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'title'=>'Jobcenter-Medizin', + 'url'=>'http://www.jobcenter-medizin.de', + 'assgiment'=>'Screendesign', + 'client'=>'BSMO GmbH', + 'shortname'=>'jobcenter-medizin', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'url'=>'http://www.berlincitypoker.de', + 'shortname'=>'poker', + 'title'=>'Berlin City Poker', + 'client'=>'André K.', + 'assignment'=>'Kommunikationskonzept / Screendesign', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'url'=>'http://www.viveo150.de', + 'shortname'=>'viveo', + 'title'=>'Viveo', + 'client'=>'Schütz & co Werbeagentur', + 'assignment'=>'Navigationskonzept / Screendesign', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'url'=>'http://weigend.com', + 'shortname'=>'weigend', + 'title'=>'Andreas S. Weigend', + 'client'=>'3-point concepts', + 'assignment'=>'Navigationskonzept / Screendesign', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'url'=>'/public/img/web/sideshow/landingpage_03.jpg', + 'shortname'=>'jamba', + 'title'=>'Landingpage "Rock"', + 'client'=>'Jamba GmbH', + 'assignment'=>'Kommunikationskonzept / Screendesign', + 'url_text'=>' Screenshot' + ); + + $projects[] = array( + 'url'=>'http://nugg.ad', + 'shortname'=>'nuggad', + 'title'=>'nugg.ad', + 'client'=>'3-point concepts', + 'assignment'=>'Navigationskonzept / Screendesign', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'url'=>'http://www.bpb.de/methodik/ZOAUGM,0,0,WahlOMat_Archiv.html', + 'shortname'=>'walomat', + 'title'=>'Wal-O-Mat', + 'client'=>'3-point concepts', + 'assignment'=>'Screendesign', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'url'=>'http://www.bildungslueckenfueller.de/', + 'shortname'=>'bildung', + 'title'=>'Bildungslückenfüller', + 'client'=>'3-point concepts', + 'assignment'=>'Navigationskonzept / Screendesign', + 'url_text'=>'Webseite besuchen' + ); + + $projects[] = array( + 'url'=>'http://www.efors.eu/', + 'shortname'=>'efors', + 'title'=>'Efors Onlinemagazin', + 'client'=>'Work-Out', + 'assignment'=>'Navigationskonzept / Screendesign', + 'url_text'=>'Webseite besuchen' + ); + + $web_projects = array(); + foreach( $projects as $project ) { + $web_projects[] = $this->factory->get_structure('portfolio/webdesign', $project); + } + + return $web_projects; + } + + public function get_print_projects() { + $projects = array(); + + $projects[] = array( + 'shortname'=>'dao', + 'title'=>'DAO', + 'client'=>'DAO - Kampfkunstschule', + 'assignment'=>'Drucksachen' + ); + + $projects[] = array( + 'shortname'=>'nanologika', + 'title'=>'nanoLogika', + 'client'=>'nanoLogika', + 'assignment'=>'Drucksachen' + ); + + $projects[] = array( + 'shortname'=>'corpuscare', + 'title'=>'corpuscare', + 'client'=>'corpuscare', + 'assignment'=>'Drucksachen' + ); + + $projects[] = array( + 'shortname'=>'poker', + 'title'=>'Berlin City Poker', + 'client'=>'Berlin City Poker', + 'assignment'=>'Drucksachen' + ); + + $projects[] = array( + 'shortname'=>'nobilis', + 'title'=>'Nobilis', + 'client'=>'Nobilis', + 'assignment'=>'Corporate Identity' + ); + + /** + $projects[] = array( + 'shortname'=>'giata', + 'title'=>'GIATA Videoaufsteller', + 'client'=>'GIATA mbH', + 'assignment'=>'Drucksachen' + ); + */ + + $projects[] = array( + 'shortname'=>'rampenlicht', + 'title'=>'Rampenlicht', + 'client'=>'Rampenlicht', + 'assignment'=>'Visitenkarten' + ); + + $print_projects = array(); + foreach( $projects as $project ) { + $print_projects[] = $this->factory->get_structure('data', $project); + } + + return $print_projects; + } + + public function get_logo_projects() { + $projects = array(); + + $projects[] = array( + 'shortname'=>'myhotelvideo', + 'title'=>'MyHotelVideo', + 'client'=>'GIATA mbH' + ); + + $projects[] = array( + 'shortname'=>'nanologika', + 'title'=>'nanoLogika', + 'client'=>'nanoLogika' + ); + + $projects[] = array( + 'shortname'=>'travelclips', + 'title'=>'travelClips', + 'client'=>'travelClips' + ); + + $projects[] = array( + 'shortname'=>'corpuscare', + 'title'=>'corpusCare', + 'client'=>'corpusCare' + ); + + $projects[] = array( + 'shortname'=>'nobilis', + 'title'=>'Nobilis', + 'client'=>'Nobilis' + ); + + + $logo_projects = array(); + foreach( $projects as $project ) { + $logo_projects[] = $this->factory->get_structure('data', $project); + } + + return $logo_projects; + } +} diff --git a/app/modules/portfolio/modul.php b/app/modules/portfolio/modul.php new file mode 100644 index 0000000..96257ec --- /dev/null +++ b/app/modules/portfolio/modul.php @@ -0,0 +1,17 @@ + + * @version 0.1.7 + * @license All Rights Reserved + */ + +/** + * Allgemeines zum Modul + */ +class portfolio_modul extends fl_modul { +} +?> diff --git a/app/modules/portfolio/view.php b/app/modules/portfolio/view.php new file mode 100644 index 0000000..0dbfe99 --- /dev/null +++ b/app/modules/portfolio/view.php @@ -0,0 +1,10 @@ + diff --git a/app/modules/portfolio/views/drucksachen.php b/app/modules/portfolio/views/drucksachen.php new file mode 100644 index 0000000..25da912 --- /dev/null +++ b/app/modules/portfolio/views/drucksachen.php @@ -0,0 +1,20 @@ +get_element('subnavigation_portfolio', array('aktiv'=>'drucksachen')); ?> + +
+

Drucksachen

+ say('page_navigator', 'string', null, true); ?> + + get('referenzen') as $projekt ) { ?> +
+
<?php $projekt->say('title'); ?>
+
+

say('title'); ?>

+

Kunde: say('client'); ?>

+

Auftrag: say('assignment'); ?>

+
+
+ + + + say('page_navigator', 'string', null, true); ?> +
diff --git a/app/modules/portfolio/views/logo.php b/app/modules/portfolio/views/logo.php new file mode 100644 index 0000000..88c9cc0 --- /dev/null +++ b/app/modules/portfolio/views/logo.php @@ -0,0 +1,21 @@ +get_element('subnavigation_portfolio', array('aktiv'=>'logo')); ?> + +
+

Logos/ Bildmarken

+ say('page_navigator', 'string', null, true); ?> + + get('referenzen') as $projekt ) { ?> +
+
<?php $projekt->say('title'); ?>
+
+

say('title'); ?>

+

Kunde: say('client'); ?>

+

Auftrag: Logoentwicklung

+
+
+ + + + say('page_navigator', 'string', null, true); ?> + +
diff --git a/app/modules/portfolio/views/webdesign.php b/app/modules/portfolio/views/webdesign.php new file mode 100644 index 0000000..f29ccdc --- /dev/null +++ b/app/modules/portfolio/views/webdesign.php @@ -0,0 +1,22 @@ +get_element('subnavigation_portfolio', array('aktiv'=>'webdesign')); ?> + +
+

Webseiten-Projekte

+ say('page_navigator', 'string', null, true); ?> + + get('referenzen') as $projekt ) { ?> +
+
say('link'); ?>
+
+

say('title'); ?>

+

Kunde: say('client'); ?>

+

Auftrag: say('assignment'); ?>

+

say('url_text'); ?>

+
+
+ + + + say('page_navigator', 'string', null, true); ?> + +
diff --git a/app/modules/user/controller.php b/app/modules/user/controller.php new file mode 100644 index 0000000..d0abcf3 --- /dev/null +++ b/app/modules/user/controller.php @@ -0,0 +1,182 @@ +check_login('user/'); + $this->data['title'] = 'Benutzer-Administration'; + } + + function add($param='') { + $this->check_login('user/add/'); + $this->data['title'] = "Neuen Benutzer anlegen"; + + if ( $param == 'save') { + $data = ( isset( $_POST['fl'] ))? $_POST['fl']: $this->goToTarget('user/add/'); + + $this->functions->needs('validation'); + $val = new validation(); + + $val->set_rule('mail', 'email'); + $val->set_msg('mail', 'Bitten geben Sie eine gültige e-mail-Adresse an.'); + + $errors = $val->validate_form($data); + + if( $this->model->doesnt_exist($data['name']) == FALSE ) { + $errors[] = 'Der Username ist bereits vergeben, bitte verwenden Sie einen anderen Namen.'; + } + + if ( !isset($data['password1']) OR ( empty($data['password1']) AND empty($data['password2']) ) ) { + $data['password1'] = $data['password2'] = $this->model->generate_PW(); + } + + if ( $data['password1'] != $data['password2'] ) { + $errors[] = 'Es wurden zwei verschiedene Passwörter eingetragen'; + } + + if ( count($errors) == 0 ) { + $created = $this->model->create_user($data); + $msg = ( $created == TRUE )? + 'Benutzer '.$data['name'].' wurde angelegt': + 'Fehler beim Anlegen des neuen Benutzers'; + + $this->flash($msg); + + if ( $created == TRUE ) { + $sent = $this->model->notify_user($data['name'], $data['password1']); + $msg = ( $sent == TRUE )? + 'Benutzer ' . $data['name'] . ' wurde per mail an ' . $data['mail'] . ' informiert.': + 'Fehler beim versenden der mail: ' . $sent; + + $this->flash($msg); + } + } else { + $this->data += $data; + $msg = implode( '
', $errors ); + $this->flash($msg); + } + } + } + + function edit($params) { + @list($user, $action) = explode('/', $params); + if ( !isset($user) OR !is_numeric($user) ) $this->goToTarget('user/'); + + $this->check_login('user/edit/'.$user); + + if ( isset($action) AND $action == 'save' ) { + $data = ( isset( $_POST['fl'] ))? $_POST['fl']: $this->goToTarget('user/'); + + $this->functions->needs('validation'); + $val = new validation(); + + $val->set_rule('email', 'email'); + $val->set_msg('email', 'Bitten geben Sie eine gültige e-mail-Adresse an.'); + + $errors = $val->validate_form($data); + + if ( $data['password1'] == '' ) { + unset($data['password1'], $data['password2']); + } else { + if ( $data['password1'] != $data['password2'] ) { + $errors[] = 'Es wurden zwei verschiedene Passwörter eingetragen'; + } + } + + if ( count($errors) == 0 ) { + $updated = $this->model->update_user($data, $user); + $msg = ( $updated == TRUE )? + 'Benutzer '.$user.' wurde aktualisiert': + 'Fehler beim Aktialisieren des Benutzers ('.$user.')' ; + + $this->flash($msg); + $this->goToTarget('user/'); + } else { + $this->data += $data; + $msg = implode( '
', $errors ); + $this->flash($msg); + } + } else { /* Formular anzeigen */ + $result = $this->datamodel->retrieve('user', '*', 'id="'.$user.'"', '' ,'1'); + unset($result['password']); + $this->data += $result; + $this->data['title'] = "Benutzer ".$result['name']." bearbeiten"; + } + } + + function del($user) { + $user_number = (int) $user; + $this->check_login('user/del/'.$user); + $this->data['title'] = "Benutzeraccount löschen"; + + if ( $user_number > 0 AND $user_number == $user ) { + $user = $user_number; + } + + $this->data = $this->model->get_data('user', $user, 'name'); + if ( $this->data['name'] != $_SESSION['username'] ) { + $this->flash('Sie können nur Ihren eigenen Benutzeraccount löschen.'); + $this->goToTarget('user/'); + } else { + $this->data['title'] = 'Benutzer "'.$this->data['name'].'" löschen'; + if ( is_string($user) ) { + $this->flash('Warnung: Der Benutzeraccount wird endgültig gelöscht, wenn sie den unten stehenden Löschknopf betätigen.'); + } elseif ( is_numeric($user) OR empty($user) ) { + $result = ( $this->datamodel->del('user', $user) )? 'Benutzeraccount von '.$_SESSION['username'].' gelöscht.': 'Fehler beim Löschen des Benutzeraccounts '.$_SESSION['username']; + $this->flash($result); + $this->logaction($result); + $this->goToTarget(ADMINMODULE.'/logout/'); + } + } + } + + /** + * Neuen Benutzer per e-mail informieren + * + * Ein neu angelegter Benutzer erhält eine e-mail mit den Zugangsdaten. + * Wenn die mail nicht abgeschickt werden kann, werden die Zugangsdaten + * auf dem Bildschirm ausgegeben. + * + * @param array $data Array aus Username, Passwort und e-mail-Adresse + * @return array erfolgreicher mailversand und Statusmeldung. + */ + function _notifyUser($data) { + $content = "Für Sie wurde ein Benutzerkonto für die Administration der Internetseite \"http://".$_SERVER['HTTP_HOST']."\" eingerichtet.\n\nIhre Zugangsdaten lauten:\nBenutzername:\t".$data['name']."\nPasswort:\t".$data['password']."\n\nBitte ändern Sie das Passwort bei Ihrer ersten Anmeldung auf \"http://".$_SERVER['HTTP_HOST']."/user/\"."; + + $result = $this->datamodel->retrieve(ADMINMODULE.'_options', '*', "optionname='SEITENTITEL'", '', '1'); + $seitentitel = $result['value']; + + $config[mailreceipient] = $data['email']; + $config[mailtopic] = '['.$seitentitel.'] Benutzerkonto angelegt'; + $config[mailfrom] = 'usermanagement@'.$_SERVER['HTTP_HOST']; + + if ( mail($config['mailreceipient'],$config['mailtopic'],$content, "From: {$config[mailfrom]}") ) { + $notify['mailed'] = TRUE; + $notify['status'] = "Benutzer wurde per e-mail informiert."; + } else { + $notify['mailed'] = FALSE; + $notify['status'] = "

Fehler

Auf diesem Server ist kein Mailversand möglich. Bitte teilen Sie dem neuangelegten Benutzer die folgende Nachricht mit:

".nl2br($content); + } + return $notify; + } + + function common() { + if ( isset($_SESSION['username']) ) { + $this->data += $this->datamodel->retrieve('user', 'id AS my_id, email AS my_email, name AS my_name, level AS my_level', "name = '" . $_SESSION['username'] . "'", '', '1'); + } + $this->functions->needs('bereiche'); + + return TRUE; + } +} +?> diff --git a/app/modules/user/help.xml b/app/modules/user/help.xml new file mode 100644 index 0000000..47c22d9 --- /dev/null +++ b/app/modules/user/help.xml @@ -0,0 +1,8 @@ + + +

In der Benutzerverwaltung können Sie Ihren eigenen Benutzerdaten bearbeiten, einen neuen Benutzer anlegen und Ihren Benutzerzugang löschen.

+ + + + + \ No newline at end of file diff --git a/app/modules/user/layouts/admin.php b/app/modules/user/layouts/admin.php new file mode 100644 index 0000000..fb8c078 --- /dev/null +++ b/app/modules/user/layouts/admin.php @@ -0,0 +1,61 @@ +'."\n"; ?> + + + + <?php echo $this->get_field('title') ?> - <?php $this->get_siteTitle() ?> +get_element('admin_head'); ?> + + +
+ +
+

baseContent

+

» get_username(); ?> Logout

+ +
+ get_element('bc_nav'); ?> +
+ + + +

get_siteTitle(); ?>

+ get_breadcrumbs($this->cap, $this->get_field('title')); ?> +
+ + + +
+ +get_sub_view(); ?> + +
+

baseContent info

+ get_element('bc_info', array('cap'=>$this->cap, 'flash'=>$this->render_flash(), 'model'=>$this) ); ?> +
+
+ +
+

   

+ +
+ +
+ + diff --git a/app/modules/user/model.php b/app/modules/user/model.php new file mode 100644 index 0000000..5842f66 --- /dev/null +++ b/app/modules/user/model.php @@ -0,0 +1,113 @@ +datamodel->retrieve('user', 'COUNT(*) AS anzahl', "name = '".$name."'"); + $doesnt_exist = ( $result['anzahl'] == 0 )? TRUE: FALSE; + return $doesnt_exist; + } + + /** + * Ein zufälliges Passwort generieren + * + * Ausgehend von der Systemzeit wird ein 6 Zeichen langer String erzeugt, + * der als vorübergehendes Passwort verwendet werden kann. + * + * @return string zufälliges Passwort + */ + function generate_PW() { + $pass = substr(md5(uniqid(microtime())), 0, 6); + return $pass; + } + + /** + * Neues Benutzerprofil anlegen + * + * @param array $data + * @return bool + */ + function create_user($data) { + $db_data = array( + 'name'=>$data['name'], + 'email'=>$data['mail'], + 'password'=>md5($data['password1']) + ); + + $create_user = ( $this->datamodel->create('user', $db_data) )? TRUE: FALSE; + + return $create_user; + } + + /** + * Benutzerdaten speichern + * + * Die Benutzerdaten werden gespeichert. Wenn ein Password angegeben wurde, + * wird es MD5-Codiert. + * + * @param array $data + * @param int $user + * @return bool + */ + function update_user($data, $user) { + $db_data = $data; + if ( isset($data['password1']) ) $db_data['password'] = md5($data['password1']); + unset($db_data['password1'], $db_data['password2']); + + $update_user = ( $this->datamodel->update('user', $db_data, $user) )? TRUE: FALSE; + return $update_user; + } + + /** + * Benutzerdaten per mail verschicken + * + * @param string $name Benutzername + * @param string $password + * @return mixed + */ + function notify_user($name, $password='') { + $result = $this->datamodel->retrieve('user', 'email', "name = '".$name."'", '', '1'); + $mailadresse = $result['email']; + + unset($result); + $result = $this->datamodel->retrieve('basecontent_options', 'value', 'optionname="SEITENTITEL"', '', '1'); + $seitentitel = $result['value']; + + $data['name'] = $name; + $data['password'] = ( $password == '' )? 'Das Passwort wurde nicht verändert.': $password; + + $this->functions->needs('mail'); + $m = new e_mail(); + + $to = $mailadresse; + $from = 'basecontent@'.$_SERVER['HTTP_HOST']; + $topic = '['.$seitentitel.'] Benutzeraccount freigeschaltet'; + $template = file_get_contents( $this->modulepath . 'user/views/notify.tpl'); + + $text = $m->parse_template($template, $data); + + $m->set_config($to, $from, $topic); + $m->set_text($text); + $m->compose_message(); + + $notify_user = $m->send_mail(); + if (!$notify_user) $notify_user = $m->get_error(); + + return $notify_user; + } +} +?> diff --git a/app/modules/user/modul.php b/app/modules/user/modul.php new file mode 100644 index 0000000..c9bc575 --- /dev/null +++ b/app/modules/user/modul.php @@ -0,0 +1,34 @@ + + * @version 0.1.6 + * @license All Rights Reserved + */ + +/** + * Modul zentral registrieren + */ +$installed_modules[] = 'user'; + +/** + * Allgemeines zum Modul + */ +class user_modul extends fl_modul { + function get_options() { + echo ''; + } + + function get_name() { + return FALSE; + } + + function get_starttext() { + echo ''; + } +} + +?> diff --git a/app/modules/user/view.php b/app/modules/user/view.php new file mode 100644 index 0000000..3d116ec --- /dev/null +++ b/app/modules/user/view.php @@ -0,0 +1,56 @@ +data['from']; + } + */ + /** + * Benutzerlevel zurückgeben + * + * Es werden die Benutzerlevel zurückgegeben, die einem Benutzer zugeteilt werden können. + * Die Rückgabe erfolgt im Format für Dropdowns: kommaseparierte "Wert=Beschreibung"-Paare. + * + * @param int $current Der Level des aktuelle eingeloggten Benutzers + * @return string + * + * @todo Daten aus Datenbank holen. + */ + function get_levels($current) { + $get_levels = array(); + + $level = array( + #'0'=>array( + # 'level'=>0, + # 'name'=>'Besitzer' + #), + '1'=>array( + 'level'=>1, + 'name'=>'Administrator' + ), + '2'=>array( + 'level'=>2, + 'name'=>'Benutzer' + ) + ); + + foreach( $level as $value ) { + if ( $value['level'] < $current ) continue; + + $get_levels[] = $value['level'].'='.$value['name']; + } + $get_levels = implode(',', $get_levels); + + return $get_levels; + } +} +?> diff --git a/app/modules/user/views/add.php b/app/modules/user/views/add.php new file mode 100644 index 0000000..4929c2a --- /dev/null +++ b/app/modules/user/views/add.php @@ -0,0 +1,18 @@ +functions->needs('html'); + +$b = new bereiche(2); +$html = new html($this); + +?> +

Benutzer hinzufügen

+
+oben('useradd', 'Allgemeine Daten'); ?> +

get_input('name', 'Name', array('size'=>20) ); ?>

+

get_input('mail', 'e-mail' ); ?>

+

get_input('password1', 'Passwort', array('type'=>'password') ); ?>

+

get_input('password2', 'Passwort wiederholen', array('type'=>'password') ); ?>

+ +buttons('abbrechen:/user/admin/,speichern'); ?> +unten(); ?> +
diff --git a/app/modules/user/views/admin.php b/app/modules/user/views/admin.php new file mode 100644 index 0000000..b9cd3ee --- /dev/null +++ b/app/modules/user/views/admin.php @@ -0,0 +1,20 @@ + +

Benutzer (Ãœbersicht)

+ +oben("eigeneraccount", 'Eigener Account'); ?> +

Benutzername: get_field('my_name'); ?>

+

e-mail: get_field('my_email'); ?>

+ +buttons('hinzufuegen:/user/add/,weiter:allenutzer'); ?> +unten(); ?> + +oben('allenutzer', 'Alle Nutzer'); ?> + get_combined_list('user', 'id=%name% (%email%)', '/user/edit/', 'level > '.$this->data['my_level'], FALSE, 'userlist'); ?> + +buttons('zurueck:eigeneraccount,hinzufuegen:/user/add/'); ?> +unten(); ?> diff --git a/app/modules/user/views/del.php b/app/modules/user/views/del.php new file mode 100644 index 0000000..d0168ba --- /dev/null +++ b/app/modules/user/views/del.php @@ -0,0 +1,34 @@ + +

get_field('title'); ?>

+ + +
+ + + +

Bestätigung

+
 
+

Ihr Benutzeraccount wird endgültig gelöscht, nachdem Sie den "Löschen"-Knopf betätigt haben.

+
 
+

Abbrechen Löschen

+ + + +

Fehler

+
 
+

Zurück zur Startseite.

+
 
+ + + +
 
+
+ + diff --git a/app/modules/user/views/edit.php b/app/modules/user/views/edit.php new file mode 100644 index 0000000..5a87a25 --- /dev/null +++ b/app/modules/user/views/edit.php @@ -0,0 +1,19 @@ +functions->needs('html'); + +$b = new bereiche('2'); +$html = new html($this); +?> +

Benutzer get_field('name'); ?> bearbeiten

+
+oben('useredit', 'Allgemeines'); ?> +

get_field('name') ?>

+

get_input('password1', 'Passwort', array('type'=>'password') ); ?>

+

get_input('password2', 'Passwort wiederholen', array('type'=>'password') ); ?>

+

get_input('email', 'e-mail' ); ?>

+

get_dropdown('status', '0=aktiv,1=inaktiv'); ?>

+

get_dropdown('level', $this->get_levels($this->data['my_level'])); ?>

+ +buttons('abbrechen:/user/admin/,speichern'); ?> +unten(); ?> +
diff --git a/app/modules/user/views/notify.tpl b/app/modules/user/views/notify.tpl new file mode 100644 index 0000000..9d2c55e --- /dev/null +++ b/app/modules/user/views/notify.tpl @@ -0,0 +1,10 @@ +Es wurde ein Benutzeraccount für die Administration von Ma Puta angelegt. + +Benutzername: {NAME} +Passwort: {PASSWORD} + +Sie können Sie über folgende Adresse einloggen: + +http://www.maputa.com/basecontent/login +-- +baseContent ist ein Produkt der 2erlei GbR diff --git a/config/contenttype.ini b/config/contenttype.ini new file mode 100644 index 0000000..43b80ce --- /dev/null +++ b/config/contenttype.ini @@ -0,0 +1,3 @@ +[headers] +content-type=text/html +charset=utf-8 diff --git a/config/database.ini b/config/database.ini new file mode 100644 index 0000000..247206e --- /dev/null +++ b/config/database.ini @@ -0,0 +1,8 @@ +[database] +type=null +host=localhost +user=rasputin +pass=nano2erlei +database=db_2erlei + +table_prefix=fl_ diff --git a/config/database.ini.sample b/config/database.ini.sample new file mode 100644 index 0000000..f8eacfe --- /dev/null +++ b/config/database.ini.sample @@ -0,0 +1,8 @@ +[database] +type=null +host=localhost +user= +pass= +database= + +table_prefix=fl_ diff --git a/config/general.ini b/config/general.ini new file mode 100644 index 0000000..8841679 --- /dev/null +++ b/config/general.ini @@ -0,0 +1,32 @@ +[constants] +; Datenbankverwendung +; +; Wenn keine Datenbank verwendet wird, muss diese +; Konstante auf true gesetzt werden +; +no_database=false + +; Name des Administrationsmoduls angeben +; +; Wenn die Seite datenbankgestützt läuft, sollten Startbereich +; und Seitentitel aus der Datenbank geholt werden und +; über eine Administrationsoberfläche veränder sein. +; +; @name ADMINMODULE +; +adminmodule=basecontent + +; Startbereich +; +; Kann hier stehen, kannn aber auch (eleganter) über +; entsprechende Routen gesetzt werden. +; +; Da die Datenbank gefragt wird, wenn es nicht +; gesetzt wird, sollte es aber hier gesetzt werden. +; +;defaultsection=basecontent +defaultsection=pages + +; Seitentitel +; +seitentitel=2erlei diff --git a/config/lang.ini b/config/lang.ini new file mode 100644 index 0000000..64ebb91 --- /dev/null +++ b/config/lang.ini @@ -0,0 +1,13 @@ +[lang] +; Landeskuerzel der Hauptsprache +; Beispiele: en de es dk zh +default=de +; Laenderkuerzel aller Sprachen, kommasepariert +; die Reihenfolge spielt keine Rolle +; Beispiel: de,en,es,pt +all=de +; Landeskuerzel der Anwendungssprache +; Wird verwendet um die Anbindung an die Datenbank +; zu automatisieren +; Beispiele: de en +application=de diff --git a/config/routes.conf.php b/config/routes.conf.php new file mode 100644 index 0000000..f59aa1e --- /dev/null +++ b/config/routes.conf.php @@ -0,0 +1,53 @@ +'defaultController', + 'action'=>'defaultAction', + 'param'=>'', + 'lang'=>'' +); + +/** + * Routen zur Umwandlung von URL zu einem Steuerarray + */ +$default_route = new fl_route('/:controller/:action/:param'); +$default_route->set_defaults($defaults); +$default_route->set_priority(255); +$default_route->set_language_key('lang'); + +$route_with_language = new fl_route('/:lang/:controller/:action/:param'); +$route_with_language->set_defaults($defaults); +$route_with_language->set_priority(100); +$route_with_language->set_partial_regex('lang', '[a-z]{2}'); +$route_with_language->set_language_key('lang'); + +/** + * Weiterleitung der Startseite auf /pages/start + */ +$pages_start = array( + 'controller'=>'pages', + 'action'=>'start', + 'param'=>'', + 'lang'=>'' +); + +$startpage = new fl_route('/'); +$startpage->set_defaults( $pages_start ); +$startpage->set_priority(50); + +$start = new fl_route('/:lang/start/:param'); +$start->set_defaults( $pages_start ); +$start->set_partial_regex('lang', '[a-z]{2}'); +$start->set_priority( 51 ); + +/** + * Routen zur Konfiguration hinzufuegen + */ +$config['routes'][] = $start; +$config['routes'][] = $startpage; +$config['routes'][] = $route_with_language; +$config['routes'][] = $default_route; + +?> diff --git a/db/db_2erlei.sql b/db/db_2erlei.sql new file mode 100644 index 0000000..704c003 --- /dev/null +++ b/db/db_2erlei.sql @@ -0,0 +1,111 @@ +-- phpMyAdmin SQL Dump +-- version 2.7.0-pl1 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Erstellungszeit: 04. Januar 2007 um 18:52 +-- Server Version: 5.0.18 +-- PHP-Version: 5.1.1 +-- +-- Datenbank: `db_2erlei` +-- + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `fl_basecontent` +-- + +DROP TABLE IF EXISTS `fl_basecontent`; +CREATE TABLE `fl_basecontent` ( + `id` int(10) unsigned NOT NULL auto_increment, + `name` varchar(20) NOT NULL default '', + `ip` varchar(15) NOT NULL, + `date` datetime NOT NULL default '0000-00-00 00:00:00', + `action` text NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0; + +-- +-- Daten für Tabelle `fl_basecontent` +-- + +INSERT INTO `fl_basecontent` VALUES (1, 'matthias', '127.0.0.1', '2007-01-04 18:01:34', 'matthias hat sich eingeloggt'); + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `fl_basecontent_options` +-- + +DROP TABLE IF EXISTS `fl_basecontent_options`; +CREATE TABLE `fl_basecontent_options` ( + `id` tinyint(3) unsigned NOT NULL auto_increment, + `optionname` varchar(50) default NULL, + `value` varchar(100) default NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0; + +-- +-- Daten für Tabelle `fl_basecontent_options` +-- + +INSERT INTO `fl_basecontent_options` VALUES (1, 'SEITENTITEL', 'Kundenlogin'); +INSERT INTO `fl_basecontent_options` VALUES (2, 'DEFAULTSECTION', 'pages'); +INSERT INTO `fl_basecontent_options` VALUES (3, 'ADMINHELP', 'sichtbar'); + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `fl_user` +-- + +DROP TABLE IF EXISTS `fl_user`; +CREATE TABLE `fl_user` ( + `id` tinyint(4) NOT NULL auto_increment, + `status` tinyint(3) unsigned NOT NULL default '0', + `name` varchar(20) default NULL, + `password` varchar(255) default NULL, + `email` varchar(255) default NULL, + `level` tinyint(3) unsigned NOT NULL default '255', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- +-- Daten für Tabelle `fl_user` +-- + +INSERT INTO `fl_user` VALUES (1, 0, 'matthias', '598d4c200461b81522a3328565c25f7c', 'matthias@2erlei.de', 0); +INSERT INTO `fl_user` VALUES (2, 0, 'bastian', 'b9d519a644a0590327bc0e3ef6505539', 'bastian@2erlei.de', 1); +INSERT INTO `fl_user` VALUES (3, 0, 'norman', 'b9d519a644a0590327bc0e3ef6505539', 'norman@2erlei.de', 2); + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `fl_user_access` +-- + +DROP TABLE IF EXISTS `fl_user_access`; +CREATE TABLE `fl_user_access` ( + `id` int(10) unsigned NOT NULL auto_increment, + `controller` varchar(255) NOT NULL, + `action` varchar(255) NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 PACK_KEYS=0; + +-- +-- Daten für Tabelle `fl_user_access` +-- + +INSERT INTO `fl_user_access` VALUES (1, 'basecontent', 'show', 2); +INSERT INTO `fl_user_access` VALUES (2, 'basecontent', 'trashcan', 1); +INSERT INTO `fl_user_access` VALUES (3, 'basecontent', 'logout', 255); +INSERT INTO `fl_user_access` VALUES (4, 'basecontent', 'options', 1); +INSERT INTO `fl_user_access` VALUES (5, 'basecontent', 'protocol', 1); +INSERT INTO `fl_user_access` VALUES (6, 'basecontent', 'support', 1); +INSERT INTO `fl_user_access` VALUES (7, 'user', 'add', 2); +INSERT INTO `fl_user_access` VALUES (8, 'user', 'edit', 2); +INSERT INTO `fl_user_access` VALUES (9, 'user', 'del', 1); +INSERT INTO `fl_user_access` VALUES (10, 'user', 'admin', 2); + diff --git a/fl/data/access.php b/fl/data/access.php new file mode 100644 index 0000000..639c113 --- /dev/null +++ b/fl/data/access.php @@ -0,0 +1,48 @@ +get('path', 'lib') . 'data/access/' . $type . '.php'; + $this->data_source = new $object_name($config); + } + + /** + * Datenzugriffsobjekt zurückgeben + * + * @return data_access + */ + public function get_data_source() { + return $this->data_source; + } +} +?> diff --git a/fl/data/access/database.php b/fl/data/access/database.php new file mode 100644 index 0000000..c61c24b --- /dev/null +++ b/fl/data/access/database.php @@ -0,0 +1,88 @@ +retrieve($table, 'COUNT(*) AS anzahl', $condition); + $anzahl = (integer) $result[0]['anzahl']; + return $anzahl; + } + + /** + * ID holen + * + * @param string $table Tabelle in der DB + * @param string $condition Bedingung, mit der gesucht werden + * @return integer + */ + public function find_id($table, $condition) { + $result = $this->retrieve($table, 'id', $condition); + $id = (integer) $result['id']; + return $id; + } + + /** + * Zuletzt einfügte ID zurückgeben + * + * @param string $table + * @return integer + */ + abstract public function last_insert_id($table); + + /** + * Eindeutigen Bezeichner für eine Tabelle zurückgeben + * + * @param string $table + * @return string + */ + abstract public function get_table_name($table); + + /** + * Datenbankabfragen loggen + */ + protected function log_query($sql) { + $this->lastSQL = $sql; + $this->allSQL[] = $sql; + $this->query_count++; + } + + /** + * Fehlermeldungen ausgeben und Ausführung stoppen + * + * @param string $error + * @param string $sql + */ + protected function error($error, $sql) { + if ( $this->show_errors OR + ( error_reporting() > 0 AND ini_get('display_errors') == 1 ) ) { + $factory = new fl_factory(); + $err = $factory->get_helper('var_analyze', 'data-access', 'Fehler'); + $err->sql($sql, 'Datenbankabfrage, die zu Fehler gefuehrt hat'); + + /** + * Um mehr Informationen mit xDebug erhalten zu koennen, + * das Datenbankobjekt in den lokalen Scope holen + */ + $database_object = $this; + } + + throw new Exception($error); + } +} +?> diff --git a/fl/data/access/mysql.php b/fl/data/access/mysql.php new file mode 100644 index 0000000..888c215 --- /dev/null +++ b/fl/data/access/mysql.php @@ -0,0 +1,348 @@ +table_prefix = (string) $config['table_prefix']; + $this->_open_db($config['host'], $config['database'], $config['user'], $config['pass']); + } + + /** + * Datenbankeintrag erzeugen + * + * Die create-Methode bietet eine Schnittstelle, um Daten zur Datenbank + * hinzuzufügen. + * + * @param string $table Tabellenname + * @param array $data assoziatives Array, das die Daten enthält. + * @param string $type Art der Einfügeoperation (INSERT, INSERT IGNORE, REPLACE) + * @return string Ergebnis der Datenbankoperation + */ + public function create($table, array $data, $type='INSERT') { + $data_length = count($data); + $i = 0; + + switch ( strtoupper($type) ) { + case 'IGNORE': + case 'INSERT IGNORE': + $type = 'INSERT IGNORE'; + break; + + case 'REPLACE': + case 'INSERT': + $type = strtoupper($type); + break; + + default: + $type = 'INSERT'; + break; + } + + $sql = $type . " INTO ".$this->get_table_name($table)." SET "; + foreach ($data as $field=>$content) { + $this->_secureFieldContent($content); + + $sql .= " ".$field."='".$content."'"; + if ( ( $data_length - 1 ) > $i++ ) + $sql .= ","; + } + + $result = $this->query($sql); + return $result; + } + + /** + * Datenbankeintrag holen + * + * Die retrieve-Methode bietet eine Schnittstelle, um Daten aus der + * Datenbank zu lesen. + * + * @param string $table Tabellenname + * @param string $field Feldnamen, die abgefragt werden + * @param string $condition Bedigungen, nach denen die Tabellenzeilen ausgewählt werden + * @param string $order Sortierungsreihenfolge + * @param string $limit maximale Anzahl von Zeilen + * @return array Assoziatives Array mit den Daten. + */ + public function retrieve($table, $field='*', $condition='', $order='', $limit='') { + if ( $limit == '') { + $sql_limit = FALSE; + } elseif ( strpos($limit, ',') === FALSE ) { + $sql_limit = '0,' . $limit; + } else { + $sql_limit = $limit; + } + + $sql = "SELECT ".$field." FROM ".$this->get_table_name($table); + if ( !empty($condition) ) + $sql .= " WHERE ".$condition; + if ( !empty($order) ) + $sql .= " ORDER BY ".$order; + if ( $sql_limit !== FALSE ) + $sql .= " LIMIT ".$sql_limit; + + $result = $this->query($sql); + return $result; + } + + /** + * Datenbankeintrag aktualisieren + * + * Die update-Methode bietet eine Schnittstelle, um Daten in der Datenbank + * zu aktualisieren. Dies ist die vermutlich die häufigste Form der + * Speicherung. + * + * @param string $table Tabellenname + * @param array $data assoziatives Array, das die Daten enthält. + * @param int $id id des Datenbankeintrages + * @param string $id_field Feldname des id-Feldes + * @param boolean $all Alle Zeilen verändern + * + * @return string Ergebnis der Datenbankoperation + */ + public function update($table, array $data, $id, $id_field='id', $all=FALSE) { + $data_length = count($data); + $i = 0; + + $sql = "UPDATE ".$this->get_table_name($table)." SET".PHP_EOL; + foreach ($data as $field=>$content) { + $this->_secureFieldContent($content); + + $sql .= " ".$field."='".$content."'"; + if ( ($data_length - 1 ) > $i++ ) + $sql .= ","; + } + if ( !$all ) { + $sql .= " WHERE ".$id_field."='".$id."'"; + } + + $result = $this->query($sql); + return $result; + } + + /** + * Datenbankeintrag löschen + * + * Die del-Methode bietet eine Schnittstelle, um Daten aus der Datenbank + * zu löschen. + * + * @param string $table Tabellenname + * @param int $id id des Datenbankeintrages + * @return boolean Ergebnis der Datenbankoperation + */ + public function del($table, $id) { + if ( !is_numeric($id) ) { + return FALSE; + } + + $sql = "DELETE FROM ".$this->get_table_name($table)." + WHERE id='".$id."' LIMIT 1"; + + $result = $this->query($sql); + return $result; + } + + /** + * Datenbank-Ergebnisse in richtige Typen umwandeln + * + * @param string table + * @param array $result + * @return array + * @todo Funktion fuer MySQL umarbeiten + */ + public function convert_result($table, $result) { + return $result; + + $table = $this->get_table_name($table); + $converted = $result; + + $sql = <<query($sql); + + foreach ( $result as $row_num => $rows ) { + foreach ( $types as $type ) { + $col = $type['col']; + $new_type = $type['type']; + $converted[$row_num][$col] = settype($row[$col], $new_type); + } + } + + return $converted; + } + + /** + * Tabelle leeren + * + * @param string $table Tabellennname + * @return boolean + */ + public function clear_table($table) { + $sql = 'TRUNCATE TABLE '.$this->get_table_name($table); + + $result = (boolean) $this->query($sql); + return $result; + } + + /** + * Tabelle optimieren + * + * @param string $table Tabellenname + * @return boolean + */ + public function optimize_table($table) { + $sql = 'OPTIMIZE TABLE ' . $this->get_table_name($table); + + $result = (boolean) $this->query($sql); + return $result; + } + + /** + * Datenbankabfrage als SQL abgeben + * + * @param string $sql + * @return mixed + */ + public function query($sql) { + return $this->_query_db($sql); + } + + /** + * Zuletzt eingefügte ID zurückgeben + * + * @param string $table + * @return integer + */ + public function last_insert_id($table) { + return mysql_insert_id($this->connection); + } + + /** + * Eindeutigen Bezeichner für eine Tabelle zurückgeben + * + * @param string $table + * @return string + */ + public function get_table_name($table) { + return $this->table_prefix . $table; + } + + // interne Funktionen + /** + * Datenbankverbindung öffnen + * + * @param string $host + * @param string $db + * @param string $user + * @param string $pass + */ + private function _open_db($host, $db, $user, $pass) { + if ( !extension_loaded('mysql') ) { + die("PHP-Erweiterung 'mysql' nicht geladen"); + } + + $this->connection = @mysql_connect( $host, $user, $pass) + OR die("Keine Verbindung zur Datenbank möglich. Fehlermeldung: ".mysql_error($this->connection)); + $this->database = $db; + + mysql_query('SET NAMES "utf8"', $this->connection); + + $this->_select_db(); + } + + /** + * Datenbank auswählen + */ + private function _select_db() { + mysql_select_db($this->database) + OR die("Konnte Datenbank nicht benutzen, Fehlermeldung: ".mysql_error()); + } + + /** + * Datenbank abfragen + * + * @param mixed $sql String oder Array, das die SQL-Abfragen enthält + * @todo Funktion überarbeiten + * @return mixed + */ + private function _query_db($sql) { + $this->_select_db(); + + if ( is_array($sql) ) { + foreach ( $sql as $nr => $query ) { + $output[$nr] = $this->query( $query ); + } + + } else { + $this->log_query($sql); + + $output = array(); + $aktionen = array('UPDATE','DELETE', 'ALTER ', 'CREATE', 'DROP T', 'TRUNCA', 'REPLAC', 'OPTIMI'); + + $abfrage = is_string($sql) ? trim($sql) : $this->error('Fehlerhafte Daten', $sql); + + $result = mysql_query($abfrage, $this->connection) OR $this->error(mysql_error($this->connection), $sql); + + $abfragetyp = strtoupper(substr($abfrage,0,6)); + + if ( ( in_array($abfragetyp,$aktionen) ) ) { + $output = ( $result )? TRUE: FALSE; + } elseif ( ($abfragetyp == 'INSERT') ) { + $output = ( $result )? $this->last_insert_id(): FALSE; + } else { + while($row = mysql_fetch_assoc($result)) { + $output[] = $row; + } + } + unset($abfragetyp); + unset($aktionen); + + } + return $output; + } + + /** + * Feldinhalte gegen Hackingversuche schützen + * + * Dies sind nur grundlegende Schutzmaßnahmen + * + * @param mixed &$var + */ + private function _secureFieldContent(&$var){ + if ( is_array($var) ) { + $varvalue = var_export($var, TRUE); + $this->error('Array sollte gespeichert werden.', $varvalue ); + } + $var = mysql_real_escape_string($var, $this->connection); + } +} +?> diff --git a/fl/data/access/null.php b/fl/data/access/null.php new file mode 100644 index 0000000..e583b40 --- /dev/null +++ b/fl/data/access/null.php @@ -0,0 +1,46 @@ + diff --git a/fl/data/access/pgsql.php b/fl/data/access/pgsql.php new file mode 100644 index 0000000..e84f21e --- /dev/null +++ b/fl/data/access/pgsql.php @@ -0,0 +1,379 @@ +table_prefix = (string) $config['table_prefix']; + $this->schema = ( isset($config['schema']) )? + $config['schema']: + 'public'; + + $this->_open_db($config['host'], $config['database'], $config['user'], $config['pass']); + } + + /** + * Datenbankeintrag erzeugen + * + * Die create-Methode bietet eine Schnittstelle, um Daten zur Datenbank + * hinzuzufügen. + * + * @param string $table Tabellenname + * @param array $data assoziatives Array, das die Daten enthält. + * @param string $type Art der Einfügeoperation (INSERT, INSERT IGNORE, REPLACE) + * @return string Ergebnis der Datenbankoperation + */ + public function create($table, array $data) { + $rows = array_keys($data); + + $values = array(); + foreach( array_values($data) as $value ) { + $values[] = $this->_secureFieldContent($value); + } + + $sql = 'INSERT INTO '. $this->_tableName($table); + $sql .= ' ( ' . implode(', ', $rows) . ' ) '; + $sql .= " VALUES ( '". implode("', '", $values) . "' );"; + + return ( $this->query($sql) )? + $this->last_insert_id($table): + false; + } + + /** + * Datenbankeintrag holen + * + * Die retrieve-Methode bietet eine Schnittstelle, um Daten aus der + * Datenbank zu lesen. + * + * @param string $table Tabellenname + * @param string $field Feldnamen, die abgefragt werden + * @param string $condition Bedigungen, nach denen die Tabellenzeilen ausgewählt werden + * @param string $order Sortierungsreihenfolge + * @param string $limit maximale Anzahl von Zeilen + * @return array Assoziatives Array mit den Daten. + */ + public function retrieve($table, $field='*', $condition='', $order='', $limit='') { + if ( $limit == '') { + $sql_limit = false; + } elseif ( strpos($limit, ',') === false ) { + $sql_limit = '0,' . $limit; + } else { + $sql_limit = $limit; + } + + $sql = 'SELECT '.$field.' FROM '.$this->schema.'.'.$this->table_prefix.$table; + if ( !empty($condition) ) + $sql .= ' WHERE '.$condition; + if ( !empty($order) ) + $sql .= ' ORDER BY '.$order; + if ( $sql_limit !== false ) { + list($offset, $sql_limit) = explode(',', $sql_limit); + $sql .= ' LIMIT '.$sql_limit . ' OFFSET '. $offset; + } + + $sql .= ';'; + + $result = $this->query($sql); + + if ( $result === false ) { + $result = array(); + } + + return $result; + } + + /** + * Datenbankeintrag aktualisieren + * + * Die update-Methode bietet eine Schnittstelle, um Daten in der Datenbank + * zu aktualisieren. Dies ist die vermutlich die häufigste Form der + * Speicherung. + * + * @param string $table Tabellenname + * @param array $data assoziatives Array, das die Daten enthält. + * @param int $id id des Datenbankeintrages + * @param string $id_field Feldname des id-Feldes + * @param boolean $all Alle Zeilen verändern + * + * @return string Ergebnis der Datenbankoperation + */ + public function update($table, array $data, $id, $id_field='id', $all=FALSE) { + $data_length = count($data); + $i = 0; + + $sql = "UPDATE ".$this->table_prefix.$table." SET".PHP_EOL; + foreach ($data as $field=>$content) { + $this->_secureFieldContent($content); + + $sql .= " ".$field."='".$content."'"; + if ( ( $data_length - 1 ) > $i++ ) + $sql .= ","; + } + if ( !$all ) { + $sql .= " WHERE ".$id_field."='".$id."' ;"; + } else { + $sql .= ';'; + } + + $result = $this->query($sql); + return $result; + } + + /** + * Datenbankeintrag löschen + * + * Die del-Methode bietet eine Schnittstelle, um Daten aus der Datenbank + * zu löschen. + * + * @param string $table Tabellenname + * @param int $id id des Datenbankeintrages + * @return boolean Ergebnis der Datenbankoperation + */ + public function del($table, $id) { + if ( !is_numeric($id) ) { + return FALSE; + } + + $sql = "DELETE FROM $this->table_prefix.$table WHERE id=$id;"; + + $result = $this->query($sql); + return $result; + } + + /** + * Datenbank-Ergebnisse in richtige Typen umwandeln + * + * Es werden die Datentypen boolean, integer und numeric ausgewertet. + * String-Datentypen muessen nicht ausgewertet werden, da PHP diesen + * Datentype automatisch annimmt. + * + * @param string table + * @param array $result + * @return array + */ + public function convert_result($table, $result) { + $table = $this->table_prefix . $table; + $converted = $result; + + $sql = <<query($sql); + + foreach ( $types as $type ) { + foreach ( $result as $row_num => $rows ) { + $col = $type['col']; + $new_type = $type['type']; + + if ( $new_type == 'boolean' ) { + $converted[$row_num][$col] = ( $converted[$row_num][$col] == 't' )? + (boolean) true: + (boolean) false; + } else { + settype($converted[$row_num][$col], $new_type); + } + } + } + + return $converted; + } + + /** + * Tabelle leeren + * + * @param string $table Tabellennname + * @return boolean + * @todo Funktion fuer PostgreSQL umarbeiten + */ + public function clear_table($table) { + return false; + + $sql = 'TRUNCATE TABLE '.$this->table_prefix.$table; + + $result = (boolean) $this->query($sql); + return $result; + } + + /** + * Tabelle optimieren + * + * @param string $table Tabellenname + * @return boolean + * @todo Funktion fuer PostgreSQL umarbeiten, VACCUUM + */ + public function optimize_table($table) { + return false; + + $sql = 'OPTIMIZE TABLE ' . $this->table_prefix.$table; + + $result = (boolean) $this->query($sql); + return $result; + } + + /** + * Zuletzt einfügte ID zurückgeben + * + * @param string $table + * @return integer + */ + public function last_insert_id($table) { + $result = $this->query('SELECT last_value FROM '.$this->_tableName($table).'_id_seq;'); + return $result[0]['last_value']; + } + + /** + * Datenbankabfrage als SQL abgeben + * + * @param string $sql + * @return mixed + */ + public function query($sql) { + return $this->_query_db($sql); + } + + // interne Funktionen + /** + * Datenbankverbindung öffnen + * + * @param string $host + * @param string $db + * @param string $user + * @param string $pass + */ + private function _open_db($host, $db, $user, $pass) { + if ( !extension_loaded('pgsql') ) { + die("PHP-Erweiterung 'pgsql' nicht geladen"); + } + + $conn_str = "host='$host' user='$user' password='$pass' dbname='$db'"; + + if ( !($this->connection = pg_connect($conn_str)) ) { + die('Keine Verbindung zur Datenbank möglich. (Fehlermeldung: '.pg_last_error().')'); + } + + pg_set_client_encoding($this->connection, 'utf8'); + } + + /** + * Datenbank abfragen + * + * @param mixed $sql String oder Array, das die SQL-Abfragen enthält + * @return mixed + */ + private function _query_db($sql) { + if ( is_array($sql) ) { + foreach ( $sql as $nr => $query ) { + $output[$nr] = $this->query( $query ); + } + + } else { + $this->log_query($sql); + + $output = array(); + + $abfrage = is_string($sql) ? trim($sql) : $this->error('Fehlerhafte Daten', $sql); + $abfragetyp = strtoupper(substr($abfrage,0,6)); + + /* Asynchrone Abfrage + if (!pg_connection_busy($this->connection)) { + pg_send_query($this->connection, $abfrage); + } else { + $this->_error('Verbindung ausgelastet'); + } + + $result = pg_get_result($this->connection); + + // pg_result_error gibt einen String zurück, wenn ein Fehler + // vorliegt und FALSE, wenn kein Fehler vorliegt. + // Es scheint aber auch einen leeren String zurückzugeben, wenn + // kein Fehler vorliegt. + $error = pg_result_error($result); + if( is_string($error) AND trim($error) !== '' ) { + $this->_error($error, $abfrage); + } else { + $this->query_count++; + $result_status = pg_result_status($result); + } + */ + + /* Einzelne, synchrone Abfrage */ + if ( ($result = pg_query($this->connection, $abfrage)) === false ) { + $this->error(pg_last_error($this->connection), $abfrage); + } else { + $result_status = pg_result_status($result); + } + + + if ( $abfragetyp !== 'SELECT' ) { + $output = ( $result_status === PGSQL_COMMAND_OK )? + true: + false; + } else { + $output = pg_fetch_all($result); + + if ( count($output) > 100 ) { + pg_free_result($result); + } + } + unset($abfragetyp); + + } + return $output; + } + + /** + * Tabellenbezeichner herstellen + * + * @param string $table + * @return string + */ + protected function _tableName($table) { + return $this->schema . '.' . $this->table_prefix . $table; + } + public function get_table_name($table) { + return $this->_tableName($table); + } + + /** + * Feldinhalte gegen Hackingversuche schützen + * + * Dies sind nur grundlegende Schutzmaßnahmen + * + * @param mixed &$var + */ + protected function _secureFieldContent(&$var){ + if ( is_array($var) ) { + $varvalue = var_export($var, TRUE); + $this->error('Array wurde uebergeben, kann aber nicht gespeichert werden.', $varvalue ); + } + return $var = pg_escape_string($var); + } +} +?> diff --git a/fl/data/structures.php b/fl/data/structures.php new file mode 100644 index 0000000..c974704 --- /dev/null +++ b/fl/data/structures.php @@ -0,0 +1,97 @@ + + * @package federleicht + * @subpackage base + */ +class fl_data_structures { + protected $libpath; + protected $modulepath; + public $built_in; + + /** + * Konstruktor + */ + public function __construct() { + $registry = fl_registry::getInstance(); + $this->libpath = $registry->get('path', 'lib'); + $this->modulepath = $registry->get('path', 'module'); + + $this->built_in = '%%builtin'; + + $this->load_structure($this->built_in, 'data'); + $this->load_structure($this->built_in, 'image'); + } + + /** + * Datenstrukturdatei zurueckgeben + * + * @param string $wanted_structure + * @param array $initial_data + * @return data_structure + */ + public function get($wanted_structure, $initial_data = array()) { + if ( strpos($wanted_structure, '/') === false) { + $modul = $this->built_in; + $name = $wanted_structure; + $structure_name = 'fl_data_structures_' . $name; + + } else { + list($modul, $name) = explode('/', $wanted_structure, 2); + $structure_name = $name . '_data'; + } + + $this->load_structure($modul, $name); + + return new $structure_name((array) $initial_data); + } + + /** + * Datenstrukturdatei einlesen + * + * @param string $modul + * @param string $name + */ + public function load_structure($modul, $name) { + if ( $modul === $this->built_in ) { + $file = $this->libpath . 'data/structures/'.$name.'.php'; + } else { + $file = $this->modulepath . $modul.'/data/'.$name.'.php'; + } + + require_once $file; + } + + /** + * Datenstrukturdatei einlesen + * + * @param string $wanted_structure + * @deprecated + */ + public function load($wanted_structure) { + trigger_error( + 'deprecated, use load_structure($modul, $name) instead', + E_USER_WARNING + ); + + return $this->load_structure($this->built_in, $wanted_structure); + } + + /** + * Pruefung, ob Datenstrukturdatei existiert + * + * @param string $modul + * @param string $name + * @return boolean + */ + public function exists($modul, $name) { + $filename = ( $modul === $this->built_in )? + $this->libpath . 'data/structures/'.$name.'.php': + $this->modulepath.$modul.'/data/'.$name.'.php'; + + return file_exists($filename); + } +} diff --git a/fl/data/structures/activerecord.php b/fl/data/structures/activerecord.php new file mode 100644 index 0000000..1e36249 --- /dev/null +++ b/fl/data/structures/activerecord.php @@ -0,0 +1,229 @@ + + * @version 0.2 + * @package federleicht + * @subpackage data + * @todo $fields automatisch aus Datenbank auslesen + * @todo validator in Basisklasse instanziieren? + * @todo active_record als Datenzugriffsklasse (und nicht als Datenstruktur) im richtigen Verzeichnis ablegen und von dort laden lassen. + * @todo active_record sollte auch das Interface data_access und data_wrapper implementieren, da es sowohl Datenzugriff wie Daten selbst darstellt. + */ +abstract class fl_data_structures_activerecord implements data_wrapper { + /** + * Instanzvariablen + */ + protected $db = null; + protected $table = ''; + protected $data = null; + public $id = null; + + public $error_messages = array(); + + /** + * Konstruktor + * + * @param data_access $db + * @param string $table + * @param int $id + * @param data_wrapper $data + * @param boolean $loaded + */ + public function __construct(data_access $db, $table, $id, data_wrapper $data, $loaded=false) { + $this->db =& $db; + $this->table = ( empty($table) ) ? $this->table : $table; + $this->id = $id; + + $this->data = $data; + + if ( !$loaded ) { + $this->load(); + } + } + + /** + * Daten setzen + */ + public function set_data(array $data) { + foreach ( $data as $key => $value ) { + if ( empty($value) ) continue; + + $this->data->set($key, $value); + } + } + + /** + * Daten holen + * + * @return data_structure + */ + public function get_data() { + return clone $this->data; + } + + /** + * Daten holen und als Array zurueckgeben + * + * @return array + */ + public function get_data_as_array() { + $data = array(); + + foreach ( $this->data as $key => $value ) { + if ( empty($value) OR $value === null ) continue; + + $data[$key] = $value; + } + + return $data; + } + + /** + * Einzelnes Datenfeld ausgeben + * + * @param string $key + */ + public function say($key) { + return $this->data->say($key); + } + + /** + * Einzelnes Datenfeld holen + * + * @param string $key + * @return mixed + */ + public function get($key) { + return $this->data->get($key); + } + + /** + * Einzelnes Datenfeld setzen + * + * @param string $key + * @param mixed $value + */ + public function set($key, $value) { + return $this->data->set($key, $value); + } + + /** + * Prüfung, ob Datenfeld existiert + * + * @param string $key + * @return boolean + */ + public function is_set($key) { + return $this->data->is_set($key); + } + + /** + * Einzelnes Datenfeld löschen + * + * @param string $key + */ + public function remove($key) { + return $this->data->remove($key); + } + + /** + * Daten aus Datenbank laden + */ + public function load() { + if ( $this->id > 0 ) { + $result = $this->db->convert_result( + $this->table, + $this->db->retrieve($this->table, '*', 'id='.$this->id) + ); + $data = $result[0]; + } else { + $data = array(); + } + + $result = $this->data->set_data($data); + + if ( $this->id > 0 ) { + $this->load_additional_data_parts(); + } + + return $result; + } + + /** + * Daten in Datenbank speichern + * + * @return boolean + */ + public function save() { + $this->prepare_data(); + + if ( $this->id > 0 ) { + $result = $this->db->update($this->table, $this->get_data_as_array(), $this->id); + } else { + $result = $this->db->create($this->table, $this->get_data_as_array()); + if ( is_numeric($result) ) { + $this->id = $result; + $this->load(); + $result = true; + } + } + + return $result; + } + + /** + * Daten aus Datenbank loeschen + * + * @return boolean + */ + public function delete() { + if ( $this->id > 0 ) { + $result = $this->db->del($this->table, $this->id); + } else { + $result = false; + } + + return $result; + } + + /** + * Objekt als String verwenbar machen + */ + public function __toString() { + return (string) $this->data; + } + + /** + * Daten vorbereiten + */ + protected function prepare_data() {} + + /** + * zusätzliche Daten laden + */ + protected function load_additional_data_parts() {} + + /** + * Datenprüfung + * + * @return array + */ + public function validate_data() { + /** + * Prüfregeln durchlaufen + */ + $validator = $this->get_validator(); + $this->error_messages += $validator->validate_form($this->get_data()); + + return $this->error_messages; + } + + /** + * Datenprüfungsobjekt erzeugen + * + * @return validation + */ + abstract public function get_validator(); +} diff --git a/fl/data/structures/data.php b/fl/data/structures/data.php new file mode 100644 index 0000000..c00a2ec --- /dev/null +++ b/fl/data/structures/data.php @@ -0,0 +1,165 @@ + + * @version 0.4 + * @package federleicht + * @subpackage base + * @todo Datenstruktur "abschliessbar" machen, also hinzufuegen neuer Werte verhindern. + */ +class fl_data_structures_data implements ArrayAccess, data_wrapper { + /** + * Daten direkt ausgeben + * + * @param string $key + */ + public function say($key) { + echo $this->get($key); + } + + /** + * Daten zurückgeben + * + * @param string $key + * @return mixed + */ + public function get($key) { + return $this->_get_field($key); + } + + /** + * Daten in Datenstruktur setzen + * + * @param string $key + * @param mixed $value + */ + public function set($key, $value) { + $this->_set_field($key, $value); + } + + /** + * Daten in Datenstruktur loeschen + * + * @param string $key + */ + public function remove($key) { + $this->_unset_field($key); + } + + /** + * Ein assoziatives Array als Daten übernehmen + * + * @param array $data + */ + public function set_data(array $data) { + foreach ($data as $key => $value ) { + $this->set($key, $value); + } + } + + /** + * Pruefen, ob eine Datenfeld existiert + * + * @param string $key + * @return boolean + */ + public function is_set($key) { + return $this->_isset_field($key); + } + + public function get_data() { + throw new Exception('Funktion nicht mehr unterstuetzt. "foreach($data_structure as $key=>value) { $data[$key] = $value }" verwenden!'); + } + + /** + * Konstruktor + * + * @param array $data + */ + public function __construct($data = null) { + $this->set_data((array) $data); + } + + /** + * Datenobjekte als String verwendbar machen + */ + public function __toString() { + return 'Datenobjekt: ' . get_class($this); + } + + /** + * Methoden des Interface ArrayAccess + */ + public function offsetExists($offset) { + return $this->is_set($offset); + } + public function offsetGet($offset) { + return $this->get($offset); + } + public function offsetSet($offset, $value) { + return $this->set($offset, $value); + } + public function offsetUnset($offset) { + return $this->remove($offset); + } + /** + * ArrayAccess Ende + */ + + /** ====== Zugriffsfunktionen auf die internen Daten ====== */ + /** + * Daten aus Objekt holen + * + * @param string $key + * @return mixed + */ + protected function _get_field($key) { + if ( $this->_isset_field($key) ) { + $value = $this->$key; + } else { + $fallback_method = 'get_'.$key; + + if ( method_exists( $this, $fallback_method ) ) { + $value = $this->$fallback_method(); + } else { + $value = ( isset($this->_default) )? $this->_default: ''; + } + } + + return $value; + } + + /** + * Daten in Datenobjekt schreiben + * + * es wird eine Liste der hinzugefügten Schlüssel geführt. + * + * @param string $key + * @param mixed $value + */ + protected function _set_field($key, $value) { + $this->$key = $value; + } + + /** + * Datenfeld aus Datenobjekt loeschen + * + * @param string $key + */ + protected function _unset_field($key) { + if ( $this->_isset_field($key) ) { + unset($this->$key); + } + } + + /** + * Pruefen, ob Datenfeld existiert + * + * @param string $key + * @return boolean + */ + protected function _isset_field($key){ + return isset($this->$key); + } +} diff --git a/fl/data/structures/deleted.php b/fl/data/structures/deleted.php new file mode 100644 index 0000000..b90d0ce --- /dev/null +++ b/fl/data/structures/deleted.php @@ -0,0 +1,8 @@ + + * @version 0.3 + * @package federleicht + * @subpackage base + */ +class fl_data_structures_image extends fl_data_structures_data { + protected $src; + protected $height; + protected $width; + + /** + * Metadaten einer Bilddatei einlesen und speichern + * + * @param int $id + * @return void + */ + protected function set_image_data($id) { + $path = $this->_imagepath; + + $files = glob(ABSPATH . $path . $id . '*'); + if ( $files === false OR !isset($files[0]) ) { + $file = $path . 'dummy.jpg'; + $id = 'dummy'; + } else { + $file = $files[0]; + } + $extension = substr($file, strrpos($file, '.')); + + list($width, $height) = getimagesize($file); + + $this->set_data(array( + 'src'=>$path . $id . $extension, + 'height'=>$height, + 'width'=>$width, + )); + } + + /** + * HTML zu einem Bild ausgeben + * + * @return string + */ + public function get_image_html() { + $html = ''.$this->get('alt').''; + return $html; + } + + /** + * Object zu String umwandeln + */ + public function __toString() { + return $this->get_image_html(); + } +} diff --git a/fl/data/structures/request.php b/fl/data/structures/request.php new file mode 100644 index 0000000..30552d6 --- /dev/null +++ b/fl/data/structures/request.php @@ -0,0 +1,53 @@ + + * @package federleicht + * @subpackage base + */ +class fl_data_structures_request { + /** + * Referenz auf Routenobjekt + */ + var $route; + + /** + * Postdaten + */ + var $all_post; + var $post; + + /** + * Konstruktor + * + * Es werden die Postdaten und die gewählte Route in das Objekt übernommen + * + * @param route $route + */ + function __construct($route) { + $this->route = $route; + + $this->all_post = $_POST; + $this->post = isset($_POST['fl'])? $_POST['fl']: null; + } + + /** + * prüfen, ob Postdaten des Frameworks vorliegen. + * + * @return boolean + */ + function has_postdata() { + return ( $this->post !== null )? true: false; + } + + /** + * Getter-Methoden, die übergangsweise Zugriff auf die Werte des Routenobjekts geben + */ + function get_modul() { + return $this->route['modul']; + } +} diff --git a/fl/data/structures/response.php b/fl/data/structures/response.php new file mode 100644 index 0000000..8bf4d0e --- /dev/null +++ b/fl/data/structures/response.php @@ -0,0 +1,15 @@ + + * @package federleicht + * @subpackage base + */ +class fl_data_structures_response extends fl_data_structures_data { + protected $http_header; + protected $data; + protected $layout; + protected $subview; +} diff --git a/fl/data/structures/view.php b/fl/data/structures/view.php new file mode 100644 index 0000000..4614629 --- /dev/null +++ b/fl/data/structures/view.php @@ -0,0 +1,78 @@ +_raw_output ) { + $data = htmlentities( + html_entity_decode( + $data, + ENT_QUOTES, + 'UTF-8' + ), + ENT_QUOTES, + 'UTF-8' + ); + } + + return $data; + } + + /** + * Ausgabe ohne Umwandlung der HTML-Sonderzeichen aktivieren + * + * @param boolean $raw + */ + public function set_raw_output($raw) { + $this->_raw_output = (boolean) $raw; + } + + /** + * Zwischen direkter und umgewandelter HTML-Ausgabe umschalten + */ + public function toggle_raw_output() { + $this->set_raw_output(!$this->_raw_output); + } + + /** + * Defaultwert setzen + * + * Es wird der bisherige Defaultwert zurueckgegeben + * + * @param string $default + * @return string + */ + public function set_default($default) { + $former_default = $this->_default; + $this->_default = (string) $default; + return $former_default; + } +} diff --git a/fl/dispatch/dispatcher.php b/fl/dispatch/dispatcher.php new file mode 100644 index 0000000..d9a9d95 --- /dev/null +++ b/fl/dispatch/dispatcher.php @@ -0,0 +1,154 @@ +clean_superglobals(); + $this->lang = new fl_lang($lang['default'], $lang['all']); + } + + /** + * Route hinzufügen + * + * @param object $route + */ + public function add_route($route) { + $this->routes[] = $route; + } + + /** + * DefaultController setzen + * + * @param string $default_controller + */ + public function set_default_controller($default_controller) { + $this->default_controller = (string) $default_controller; + } + + /** + * URL Analysieren + * + * Die URL wird versucht, mit den verschiedenen Routen in Verbindung + * zu bringen. Die letzte Route wird bei Misserfolg erneut geprüft, um + * die darin gespeicherten Vorgabewerte zu nutzen. + * + * Die Sprache wird danach versucht zu extrahieren. Entweder aus dem + * Feld 'lang' oder aus dem in der Route dafür vorgemerkten Feld. + * + * Zuletzt wird der controller ggf. auf den Vorgabewert der Anwendung + * gesetzt. + * + * @param url Zu untersuchende URL + * @return array $request + */ + public function analyse($url){ + $url = preg_replace('@[/]{2,}@', '/', $url); // gegen Unsinn + + $route_success = FALSE; + usort( $this->routes, array('fl_route', 'compare_routes')); + + $request = array(); + + foreach ( $this->routes as $route ) { + if ( $route->try_route($url) ) { + $request = $route->get_request(); + $route_success = $route; + break; + } else { + continue; + } + } + if ( $route_success === FALSE ) { + $last_route = array_pop($this->routes); + $last_route->try_route($url, TRUE); + + $request = $last_route->get_request(); + $route_success = $last_route; + } + + if ( isset( $request['lang'] ) ) { + $this->lang->set($request['lang']); + } else { + $this->lang->set( $route_success->get_language_key() ); + } + + # $request['_url'] = $route_success->get_current_url(); + + if ( $request['controller'] === 'defaultController' ) { + $request['controller'] = $this->default_controller; + # $request['_url'] = str_replace('defaultController', $this->default_controller, $_url); + } + + if ( $request['modul'] === 'defaultController' ) { + $request['modul'] = $request['controller']; + } + + if ( !in_array($request['modul'], $this->modules) ) { + $request = array( + 'modul'=>$this->default_controller, + 'controller'=>$this->default_controller, + 'action'=>'defaultAction', + 'param'=>'' + ); + } + + return $request; + } + + /** + * Superglobale bereinigen + */ + protected function clean_superglobals() { + if(get_magic_quotes_gpc()) { + $this->arrayStripSlashes($_GET); + $this->arrayStripSlashes($_POST); + $this->arrayStripSlashes($_COOKIE); + } + } + + /** + * Stripslashes verallgemeinert (Strings und Arrays) + */ + protected function arrayStripSlashes(&$var) { + if ( is_string($var) ) { + $var = stripslashes($var); + } elseif( is_array($var) ) { + foreach( $var AS $key => $value ) { + $this->arrayStripSlashes($var[$key]); + } + } + } +} +?> diff --git a/fl/dispatch/lang.php b/fl/dispatch/lang.php new file mode 100644 index 0000000..2cfa29e --- /dev/null +++ b/fl/dispatch/lang.php @@ -0,0 +1,55 @@ +default_lang = $default; + $this->all = $all; + } + + public function set($page) { + $defaultlang = $this->default_lang; + $all_langs = $this->all; + if ( isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ) { // Sprache aus ACCEPT-Header herauslesen, wenn möglich + $accept_header = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); + if ( is_array($accept_header) ) { + array_unique($accept_header); + foreach( $accept_header as $language ) { + $language = substr($language, 0, 2); + if ( in_array($language, $all_langs) ) { + $defaultlang = $language; + break(1); + } + } + } + } + $temp = explode('/',$page); + if ( count($temp) >= 1 ) { + $lang = ( in_array($temp[0], $all_langs) )? array_shift($temp): $defaultlang; + $page = implode('/',$temp); + } else { + $lang = $defaultlang; + $page = implode('/',$temp); + } + + if (!defined('LANG') ) { + define('LANG', $lang); + } + $this->language = $lang; + + unset($temp, $lang, $defaultlang, $all_langs, $accept_header); + return $page; + } + + public function get_lang() { + return $this->language; + } +} diff --git a/fl/dispatch/route.php b/fl/dispatch/route.php new file mode 100644 index 0000000..e60c5b3 --- /dev/null +++ b/fl/dispatch/route.php @@ -0,0 +1,366 @@ + + * @version 0.3 + */ +class fl_route { + protected $route = ''; + protected $regex = ''; + protected $modul = ''; + protected $defaults = array(); + protected $priority = 1; + protected $language_key = ''; + + protected $default_regex = array(); + protected $partial_regex = array(); + + /** + * Konstruktor + * + * @param string $route + * @param string $regex + */ + public function __construct($route, $regex='') { + $this->route = (string) $route; + + $this->default_regex = array( + 'normal_item'=>'[-_0-9a-z\.]+', + 'last_item'=>'[-_/0-9a-zA-Z%\.]+' + ); + + if ( $route === 'regex' AND $regex != '' ) { + $this->regex = $regex; + } else { + $this->regex = $this->compile($route); + } + + $this->set_priority( 1 ); + $this->set_defaults( array() ); + } + + /** + * Vereinfachte Objekterzeugung + * + * @pattern facade + * + * @param string $route + * @param string $defaults + * @param int $priority + * @param array $partial_regex + * @return fl_route + */ + public static function get_instance($route, $defaults, $priority, array $partial_regex=array()) { + $route_object = new self($route); + + $defaults = is_string($defaults)? + fl_converter::string_to_array($defaults): + $defaults; + $route_object->set_defaults($defaults); + + $route_object->set_priority((int) $priority); + $route_object->set_language_key('lang'); + + foreach ( $partial_regex as $part ) { + $route_object->set_partial_regex($part['key'], $part['regex']); + } + + return $route_object; + } + + /** + * Route zu regulärem Asudruck umwandeln + * + * @param string $route + * @return $string + */ + protected function compile($route) { + $elements = explode('/', $route); + $group_count = 0; + + $beginning = '@^/'; + $route_regex = ''; + $end = '$@'; + + foreach( $elements as $key => $value ) { + if ( empty($value) ) { + unset($elements[$key]); + } + } + $elements = array_values($elements); + + foreach( $elements as $key => $value ) { + if ( empty($value) ) continue; + + $is_last = ( $key === ( count($elements) - 1 ) )? TRUE: FALSE; + + if ( strpos($value, ':') === 0 ) { + $name = substr($value, 1); + $transformed_route = '(?P<'.$name.'>'; + + $regex = $this->get_partial_regex($name, $is_last); + if ( !empty( $regex ) ) { + $transformed_route .= $regex; + } elseif ( $is_last ) { + $transformed_route .= $this->default_regex['last_item']; + } else { + $transformed_route .= $this->default_regex['normal_item']; + } + + $transformed_route .= ')'; + + if ( $group_count > 0 ) { + $transformed_route = '(?('.$group_count.')' . $transformed_route . '?+)'; + } + + $group_count++; + + } else { + $transformed_route = $value; + } + + $route_regex .= $transformed_route; + + if ( !$is_last ) { + $route_regex .= '(/)?'; + $group_count++; + } + } + + $regex = $beginning . $route_regex . $end; + return $regex; + } + + /** + * Versuchen, Route in URL zu erkennen + * + * @param string $url + * @param boolean $last_route + * @return boolean + */ + public function try_route($url, $last_route=FALSE) { + $treffer = array(); + + $host = ( isset($_SERVER['HTTP_HOST']) )? $_SERVER['HTTP_HOST']: 'localhost'; + $parsed_url = parse_url('http://'.$host.'/'.ltrim($url,'/')); + $url_path = $parsed_url['path']; + + $result = preg_match($this->regex, $url_path, $treffer); + + $request = $this->defaults; + $request['query'] = (isset($parsed_url['query']))? $parsed_url['query']:''; + + foreach ( $treffer as $key => $value ) { + if ( is_numeric($key) ) continue; + if ( empty($value) ) continue; + + $request[$key] = $value; + } + + if ( $url === '/' AND $last_route === TRUE ) { + $result = 1; + } + if ( $this->modul === $this->defaults['controller'] ) { + $request['modul'] = $request['controller']; + } + + $this->request = $request; + + $route_success = ( intval($result) > 0 )? TRUE: FALSE; + return $route_success; + } + + /** + * Defaultwerte setzen + * + * @param array $defaults + * @param string $modul + */ + public function set_defaults(array $defaults, $modul=NULL) { + $this->defaults = array_merge($this->defaults, $defaults); + + if ( is_null($modul) AND isset($this->defaults['controller']) ) { + $modul = $this->defaults['controller']; + } else { + $modul = ''; + } + + $this->set_modul($modul); + } + + /** + * Priorität der Route setzen + * + * @param integer $priority + */ + public function set_priority($priority) { + $this->priority = (integer) $priority; + } + + /** + * Defaultkey für Sprachinformationen setzen + * + * @param string $key + */ + public function set_language_key($key) { + $this->language_key = (string) $key; + } + + /** + * Teilregeln für einzelne Routenbestandteile setzen + * + * Nach dem setzen der Regeln wird die Route neu kompiliert. + * + * @param string $key + * @param string $regex + */ + public function set_partial_regex($key, $regex) { + $this->partial_regex[$key] = $regex; + $this->regex = $this->compile($this->route); + } + + /** + * Modulzugehörigkeit setzen + * + * @param string $modul + */ + public function set_modul($modul) { + $this->modul = (string) $modul; + } + + /** + * Request-Daten holen + * + * @return array + */ + public function get_request() { + $request = array_merge($this->request, array('modul'=>$this->modul)); + + return $request; + } + + /** + * Priorität holen + * + * @return integer + */ + public function get_priority() { + return $this->priority; + } + + /** + * Teilregel für eine Routenbestandteil holen + * + * @param string $key + * @param boolean $is_last + * @return string + */ + public function get_partial_regex($key, $is_last = false) { + if ( isset( $this->partial_regex[$key] ) ) { + $regex = $this->partial_regex[$key]; + } elseif ( $is_last ) { + $regex = $this->default_regex['last_item']; + } else { + $regex = $this->default_regex['normal_item']; + } + + return $regex; + } + + /** + * Sprachschlüssel holen + * + * Entweder ist der Sprachschlüssel mit $this->set_language_key + * gesetzt worden, oder es wird der letzte Eintrag der Default- + * Werte verwendet. + * + * @return string + */ + public function get_language_key() { + if ( isset( $this->language_key ) AND !empty($this->language_key) ) { + return $this->language_key; + } else { + return array_pop(array_keys($this->defaults)); + } + } + + /** + * URL erzeugen, die der aktuellen Route entspricht + * + * @param string $route + * @param array $parts + * @return string + */ + public function make_url($route, array $parts) { + $elements = explode('/', $route); + + $url = ''; + + foreach( $elements as $key => $value ) { + if ( empty($value) ) { + unset($elements[$key]); + } + } + $elements = array_values($elements); + + foreach( $elements as $key => $value ) { + if ( empty($value) ) continue; + + if ( strpos($value, ':') === 0 ) { + $name = substr($value, 1); + + $part = $parts[$name]; + if ( !empty( $part ) ) { + $url .= $part; + } else { + $url .= $this->defaults[$name]; + } + + } else { + $url = $value; + } + + $url .= '/'; + } + + return $url; + } + + /** + * URL zurückgeben, die zur aktuellen Route passt + * + * @return string + */ + public function get_current_url() { + return $this->make_url($this->route, $this->request); + } + + + /** + * Vergleichsfunktion zur Sortierung von Routen + * + * Kann mit usort($array_of_routes, array('route', 'compare_routes'); + * verwendet werden. + * + * @param fl_route $a + * @param fl_route $b + * @return integer + */ + public function compare_routes(fl_route $a, fl_route $b) { + $ap = $a->get_priority(); + $bp = $b->get_priority(); + + if ( $ap == $bp ) { + $result = 0; + } else { + $result = ( $ap > $bp )? 1: -1; + } + return $result; + } +} diff --git a/fl/federleicht.php b/fl/federleicht.php new file mode 100644 index 0000000..cd1669d --- /dev/null +++ b/fl/federleicht.php @@ -0,0 +1,260 @@ +ABSPATH . 'fl/', + 'app'=>ABSPATH . 'app/', + 'module'=>ABSPATH . 'app/modules/', + 'helper'=>ABSPATH . 'app/helper/', + 'elements'=>ABSPATH . 'app/elements/', + 'layouts'=>ABSPATH . 'app/layouts' + ); + + $this->import_classes($path); + + $this->registry = fl_registry::getInstance(); + $this->registry->set('url', (string) $url); + $this->registry->set('path', $path); + + $config = $this->read_config(); + $modules = $this->search_modules(); + $helpers = $this->search_helpers(); + + $this->registry->set('config', $config); + $this->registry->set('modules', $modules); + $this->registry->set('helpers', $helpers); + + $this->functions = new fl_functions(); + + if ( count($modules) == 0 ) { + $this->functions->stop('

Fehler

Keine Module installiert

'); + } + + $data = new fl_data_access($this->registry->get('config', 'database')); + + $this->datamodel = $data->get_data_source(); + $this->functions->set_data_access($this->datamodel); + } + + /** + * Federleicht starten + * + * Der Dispatcher geladen. Nach der URL-Analyse wird das + * entsprechende Modul geladen und gestartet. + */ + function start() { + $this->start_session(); + + $this->functions->start_flash(); + + if ( !defined('DEFAULTSECTION') ) { + $result = $this->datamodel->retrieve( + ADMINMODULE.'_options','value', + "optionname = 'DEFAULTSECTION'", '', '1'); + define('DEFAULTSECTION', $result['value']); + } + + $dispatcher = new fl_dispatcher($this->registry->get('config', 'lang')); + $dispatcher->modules = $this->registry->get('modules'); + $dispatcher->set_default_controller(DEFAULTSECTION); + foreach( $this->registry->get('config', 'routes') as $route ) { + $dispatcher->add_route( $route ); + } + + $request = $this->functions->factory->get_structure( + 'request', + $dispatcher->analyse( + $this->registry->get('url') + ) + ); + $this->registry->set('request', $request); + + $modul = $this->registry->get('request', 'modul'); + + require_once $this->registry->get('path', 'module') . $modul . '/modul.php'; + + $modul_name = $modul . '_modul'; + $modul_object = new $modul_name($this->datamodel, $this->functions); + $modul_object->start_execution(); + } + + /** + * Session starten + */ + function start_session() { + // Einstellungen vornehmen + // 7 * 24 * 60 * 60 = 604800 + // 40 * 60 = 2400 + #ini_set('session.gc_maxlifetime', 2400); + #ini_set('session.use_only_cookies', '1'); + + // Session stored in Cookies + #$this->functions->needs('cookiesession'); + + // Session starten + session_start(); + } + + /** + * Einbindung der autoload-Funktion + * + * @param array $path + */ + function import_classes(array $path) { + require_once $path['lib'] . 'tools/autoload.php'; + + $interfaces = array( + 'data_access', + 'data_wrapper' + ); + + foreach ($interfaces as $interface) { + require_once $path['lib'] . 'interfaces/'. $interface . '.php'; + } + + return; + } + + /** + * Nach Modulen suchen und diese einbinden + * + * Das Verzeichnis modulepath wird auf entsprechende Dateien + * untersucht. Die Liste der gefundenen Module wird zurück- + * gegeben. + * + * @return array + * @todo in Factory verschieben + */ + function search_modules() { + $modules = glob( $this->registry->get('path', 'module') . '*/modul.php'); + $installed_modules = array(); + + if ( !is_array($modules) ) return $installed_modules; + + + foreach ($modules as $module) { + $installed_modules[] = preg_replace('#'.addslashes( $this->registry->get('path', 'module') ).'([-_a-z0-9]+)/modul.php#','$1',$module); + } + + return $installed_modules; + } + + /** + * Nach Helfermodulen suchen und diese einbinden + * + * Das Verzeichnis helper wird auf entsprechende Dateien + * untersucht. Die Liste der gefundenen Helfer wird zurück- + * gegeben. + * + * @return array + * @todo in Factory verschieben + */ + function search_helpers() { + $helpers = glob( $this->registry->get('path', 'helper') . '*.php'); + $installed_helpers = array(); + + if ( !is_array($helpers) ) return $installed_helpers; + + foreach ($helpers as $helper) { + $installed_helpers[] = preg_replace('#'.addslashes($this->registry->get('path', 'helper')).'([-_a-z0-9]+)\.php#','$1',$helper); + } + + return $installed_helpers; + } + + /** + * Konfiguration einlesen + * + * Die Konfigurationsdateien werden eingelesen und deren + * Inhalt als Array zurückgegeben. + * + * @return array + */ + function read_config() { + $configfiles = glob( ABSPATH . 'config/*.ini'); + + if ( empty($configfiles) ) { + die('Keine Konfigurationsdateien gefunden.'); + } + + $config = array(); + + foreach($configfiles as $file) { + $config += parse_ini_file($file, true); + } + + /** + * Spezielle Behandlung bestimmter Einstellungen + */ + // Konstanten setzen + if ( isset( $config['constants'] ) ) { + foreach ( $config['constants'] as $key => $value ) { + define( strtoupper($key), $value ); + } + } + + // Sprachenliste in Array umwandeln + if ( isset( $config['lang'] ) ) { + $config['lang']['all'] = explode( ',', $config['lang']['all'] ); + } + + // Wenn keine Datenbankkonfiguration angegeben ist und auch nicht + // gesagt wurde, dass keine Datenbank verwendet wird, abbrechen. + if ( !in_array(ABSPATH.'config/database.ini', $configfiles) AND + ( !defined('NO_DATABASE') OR NO_DATABASE === false ) ) { + die('Keine Datenbankkonfiguration angegeben.'); + } + + /** + * Routen einlesen + */ + require_once ABSPATH . 'config/routes.conf.php'; + + return (array) $config; + } + + /** + * Federleicht anhalten + */ + function stop() { + $this->functions->stop(); + } +} +?> diff --git a/fl/interfaces/data_access.php b/fl/interfaces/data_access.php new file mode 100644 index 0000000..8d330e8 --- /dev/null +++ b/fl/interfaces/data_access.php @@ -0,0 +1,23 @@ + + * @version 0.2 + * @package federleicht + * @subpackage base + */ +interface data_access { + public function create($target, array $data); + public function retrieve($target, $fields='*', $conditions='', $order='', $limit=''); + public function update($target, array $data, $id); + public function del($target, $id); + public function query($query); +} diff --git a/fl/interfaces/data_wrapper.php b/fl/interfaces/data_wrapper.php new file mode 100644 index 0000000..bc06f64 --- /dev/null +++ b/fl/interfaces/data_wrapper.php @@ -0,0 +1,18 @@ + + * @version 0.2 + * @package federleicht + * @subpackage base + */ +interface data_wrapper { + public function set($key, $value); + public function get($key); + public function say($key); + + public function set_data(array $data); + public function is_set($key); + public function remove($key); +} diff --git a/fl/interfaces/response.php b/fl/interfaces/response.php new file mode 100644 index 0000000..1645fb7 --- /dev/null +++ b/fl/interfaces/response.php @@ -0,0 +1,21 @@ + + * @version 0.1 + * @package federleicht + * @subpackage base + */ +interface view { + public function execute($response); +} diff --git a/fl/mvc/controller.php b/fl/mvc/controller.php new file mode 100644 index 0000000..07dffbb --- /dev/null +++ b/fl/mvc/controller.php @@ -0,0 +1,251 @@ +datamodel = $data_access; + $this->functions = $functions; + $this->factory = $functions->factory; + + $this->model = $model; + + $registry = fl_registry::getInstance(); + $this->request = $registry->get('request'); + $this->cap = $this->request->route; + $this->modulepath = $registry->get('path', 'module'); + + $this->responder = $this->factory->create('responder'); + + $this->view = $this->cap['action']; + } + + /** + * Datenobjekt (bislang ein Array) holen + * + * @return fl_data_structures_response + */ + public function get_response() { + $response = $this->factory->get_structure( + 'response', + array( + 'http_header'=>array(), + 'data'=>$this->data, + 'layout'=>$this->layout, + 'subview'=>$this->view + ) + ); + + return $response; + } + + /** + * Verwaltungsobjekt für Antwortobjekte holen + * + * @return fl_responder Iterator data_wrapper + */ + public function get_responses() { + return $this->responder; + } + + /** + * Gemeinsame vorangestellte Abläufe + * + * Falls ein Modul gemeinsame, bei jedem Seitenaufruf wiederkehrende + * Aufgaben hat, können diese in der Funktion common definiert werden. + * + * Diese Funktion kann und soll ggf. von den Modulen überschrieben werden. + * + * @return bool Erfolgreiche Abarbeitung + */ + public function common() { + return TRUE; + } + + /** + * Alternative Abläufe + */ + public function alternate($e = null) { + if ( $e instanceof Exception ) { + $registry = fl_registry::getInstance(); + throw $e; + } + } + + /** + * Weiterleitung zur DefaultAction + * + * Wenn in keine Action übergeben wurde, wird die defaultAction + * ausgeführt. Diese wird von jedem Controller selbst festgelegt. + * + * Außerdem wird der Subview automatisch auf die im Controller + * festgelegte Action gesetzt. + * + * @param string $param + */ + public function defaultAction($param) { + $this->cap['action'] = $this->defaultAction; + $action = $this->defaultAction; + $this->view = $this->defaultAction; + + /** + * richtigen Wert in Registry speichern + */ + $reg =& fl_registry::getInstance(); + $request = $reg->get('request'); + $request->route['action'] = $this->defaultAction; + $reg->set('request', $request); + + $this->$action($param); + } + + /** + * Speichert eine kurze Nachricht für die Darstellung. + * + * Es kann eine "Wichtigkeit" als $type übergeben werden, diese wird + * als CSS-Klasse eingefügt. + * + * @param string $text Nachrichtentext + * @param string $type Wichtigkeit, wird als CSS-Klasse eingefügt + * @param string $namespace Gültigkeitsbereich + */ + protected function flash($text, $type='', $namespace='') { + $flash = $this->functions->flash; + + return $flash->add_message($text, $namespace, $type); + } + + /** + * Ruft eine andere URL auf. + * + * @param string $target + * @todo externes Template fuer Weiterleitungsfehler verwenden + */ + protected function redirect($target='') { + $target = ltrim($target, '/'); + + if ( defined('SUBDIR') ) { + $target = SUBDIR.'/'.$target; + } + + $zieladresse = 'http://'.$_SERVER['HTTP_HOST'].'/'.$target; + $this->functions->flash->save_messages(); + + #if ( headers_sent($file, $line) AND strlen(ob_get_contents()) > 0) { + if ( headers_sent($file, $line) ) { + if ( error_reporting() > 0 ) { + $backtrace = debug_backtrace(); + $html = <<HTTP-Header wurden bereits gesandt +

Die Ausgabe startete hier:

+
+Datei: {$file}
+Zeile: {$line}
+
+

Weitere Informationen

+
+Anfrage: {$_SERVER['REQUEST_URI']}
+Zieladresse: {$zieladresse}
+Backtrace: 
+{$backtrace}
+
+HTML; + echo $html; + } + + ob_flush(); + $this->functions->stop( + ''.$zieladresse.'' + ); + } else { + header('Location: '.$zieladresse); + ob_flush(); + } + } + + /** + * POST-Daten holen + * + * Die POST-Daten werde geholt und zurückgegeben. + * Wenn keine Daten da sind, leite den Browser auf eine + * andere Adresse um. + * + * @param string $target Zieladresse, falls keine Daten vorliegen. + * @return array + */ + protected function get_postdata($target='') { + if ( $this->request->has_postdata() ) { + $postdata = $this->request->post; + } else { + $this->redirect($target); + } + + return $postdata; + } + + /** + * Parameter auswerten + * + * @param string $params + * @return array + */ + protected function parse_params($params) { + if ( strpos($params, '/') ) { + $params = explode('/', $params); + } else { + $params = array($params); + } + + if ( func_num_args() > 1 ) { + $args = func_get_args(); + unset($args[0]); + + foreach( $args as $nr => $type ) { + $keynr = $nr - 1; + if ( !isset($params[$keynr]) ) { + $params[$keynr] = null; + } + settype($params[$keynr], $type); + } + } + + return $params; + } +} +?> diff --git a/fl/mvc/model.php b/fl/mvc/model.php new file mode 100644 index 0000000..45d8fe0 --- /dev/null +++ b/fl/mvc/model.php @@ -0,0 +1,270 @@ +datamodel = $data_access; + $this->factory = $factory; + $this->modulepath = $path; + + $class = explode('_', get_class($this)); + $this->modul = $class[1]; + + # $this->translator = $this->get_translator(); + } + + /** + * Übersetzungsobjekt holen + * + * @todo php4-Version des Ubersetzers erstellen und ggf. einbinden. + * @return GetText + */ + protected function get_translator() { + $this->functions->needs('localization'); + if ( class_exists('flGetText') AND class_exists('LocalizationDB') AND class_exists('RessourceManager') ) { + require ABSPATH . 'config/database.conf.php'; + $db_config = $config['db']; + $locale_db = new LocalizationDB( + 'localization', + $db_config['mysql_host'], + $db_config['mysql_user'], + $db_config['mysql_pass'] + ); + $rm = new RessourceManager($locale_db); + $translator = new flGetText(LANG, $rm); + } + + return $translator; + } + + /** + * Daten holen + * + * Wrappperfunktion, die entweder direkt aus der Datenbank die Daten holt, + * oder die entsprechende Funktion eines Model aufruft. + * + * @param string $modul + * @param mixed $id + * @param string $id_alternate_name + * @return array + */ + public function get_data($modul, $id, $id_alternate_name='slug') { + $model = ( $modul != $this->modul )? + $this->factory->get_model($modul): + $this; + + if ( is_numeric($id) ) $id_alternate_name = 'id'; + + $data = ( is_object($model) AND method_exists($model, 'get_data_from_model') )? + $model->get_data_from_model($id, $id_alternate_name): + $this->get_data_from_db($modul, $id, $id_alternate_name); + + return $data; + } + + /** + * Holt die Daten aus der Datenbank + * + * @param string $table Name der Tabelle + * @param mixed $page eindeutige id der Seite + * @param string $string_field Feldname, der den Speichernamen enthält + */ + protected function get_data_from_db($table, $page, $string_field='slug') { + if ( empty($page) ) { + $page = $this->datamodel->retrieve($table.'_options', 'value', "optionname = 'STARTPAGE'", '', '1'); + $page = $page['value']; + } + + if ( is_numeric($page) ) { + $condition = 'id='.$page; + } elseif ( is_string($page) ) { + $condition = $string_field.'="'.$page.'"'; + } + + $data = $this->datamodel->retrieve($table, '*', $condition, '', '1'); + + return $data; + } + + /** + * Einen Datensatz zurückgeben + * + * @param array $result Datenbankergebnis + * @param string $field optional + * @return array + * @todo ins Datenbank-Objekt! + */ + public function find_one(array $result, $field='id') { + while ( !isset($result[$field]) AND is_array($result) ) { + $result = array_shift($result); + } + + return (array) $result; + } + + /** + * Mehrere Datensätze zurückgeben + * + * @param array $result Datenbankergebnis + * @param string $field optional + * @return array + * @todo ins Datenbank-Objekt! + */ + public function find_many(array $result, $field='id') { + $result = (array) $result; + + $many_results = ( isset($result[$field]) )? + array($result): + $result; + + return $many_results; + } + + /** + * Umlaute in Daten fuer HTML umwandeln + * + * Es wird angenommen, dass ein zweidimensionales Array mit + * Datenbankergebnissen umzuwandlen ist. + * + * @param array $data + * @param string $field + * @return array + */ + public function encode_entities(array $data, $field = 'name') { + foreach($data as $key => $value ) { + $data[$key][$field] = htmlentities( + html_entity_decode( + $value[$field], + ENT_QUOTES, + 'UTF-8' + ), + ENT_QUOTES, + 'UTF-8' + ); + } + + return $data; + } + + /** + * Checkboxen in Binärzahlen umwandeln + * + * Die Funktion verhält sich standardmäßig unauffälig und übergeht fehlende + * (also auch falschgeschriebene) Indizes. Diese Verhalten kann mit dem + * optionalen Parameter $strict so verändert werden, dass fehlende Checkboxen + * mit dem Wert 0 erzeugt werden. + * + * @param array $postdata Array mit Daten + * @param string $checkboxes CSV-String der umzuwandelnden Checkboxen + * @param bool $strict nichtvorhandene Felder werden mit Wert 0 + * erzeugt + * @return array + */ + public function transform_checkboxes(array $postdata, $checkboxes, $strict = FALSE) { + $checkboxes = explode(',', $checkboxes); + $data = (array) $postdata; + + foreach( $checkboxes as $checkbox ) { + $checkbox = trim($checkbox); + + if ( !isset($data[$checkbox]) ) { + if ( $strict ) { + $data[$checkbox] = 0; + } + + continue; + } + + $data[$checkbox] = ( $data[$checkbox] === $checkbox )? + 1: + 0; + } + + return $data; + } + + /** + * Fehlermeldungen holen + * + * @return string + */ + public function get_error_messages() { + return implode('
', (array) $this->error_messages); + } + + /** + * Ãœbersetzten Text ausgeben + * + * Es wird ein Text zurückgegeben, der entweder eine Ãœbersetzung + * des übergebenen Textes ist oder der übergebene Text selbst. + * + * @todo Achtung: Funktion ist auch in fl/view.php definiert + * @param string $text + * @param string $lang + * @return string + */ + public function translate($text, $lang=LANG) { + if ( is_object($this->translator) ) { + $translation = $this->translator->get($text, $lang); + } else { + $translation = $text; + } + + return $translation; + } + + /** + * Array übersetzen + * + * @param array $array + * @param string $lang + * @param string $index + * @return array + */ + public function translate_array(array $array, $lang=LANG, $index='') { + if ( $index !== '' AND isset($array[0][$index])) { + foreach ( $array as $key => $value ) { + $array[$key][$index] = $this->translate($value[$index], $lang); + } + + } else { + foreach ( $array as $key => $value ) { + $array[$key] = $this->translate($value, $lang); + } + + } + + return $array; + } +} +?> diff --git a/fl/mvc/modul.php b/fl/mvc/modul.php new file mode 100644 index 0000000..0cacb4c --- /dev/null +++ b/fl/mvc/modul.php @@ -0,0 +1,242 @@ +datamodel = $data_access; + $this->functions = $functions; + $this->factory = $functions->factory; + $this->registry = fl_registry::getInstance(); + + $this->cap = $this->registry->get('request', 'route'); + $this->modulepath = $this->registry->get('path', 'module'); + $this->apppath = $this->registry->get('path', 'app'); + + if ( $this->name === null ) { + $this->name = ucfirst( get_class( $this ) ); + } + } + + /** + * Controller erzeugen + * + * @param string $name Modulname + * @return object + */ + protected function create_controller($name) { + require_once $this->modulepath . $name . '/controller.php'; + $controller_name = $name . '_controller'; + + $controller = new $controller_name($this->datamodel, $this->functions, $this->create_model($name)); + + return $controller; + } + + /** + * Model erzeugen + * + * @param string $name Modulname + * @return object + */ + protected function create_model($name) { + return $this->factory->get_model($name); + } + + /** + * View-Objekt erzeugen + * + * @param string $name Modulname + * @param array Daten + * @return object + */ + protected function create_view($name, array $data) { + // @todo unsauber! verbessern!!! + require_once ABSPATH . 'fl/mvc/view.php'; + + if ( file_exists($this->modulepath . $name . '/view.php') ) { + require_once $this->modulepath . $name . '/view.php'; + $view_name = $name . '_view'; + } else { + $view_name = 'fl_view'; + } + + $view = new $view_name($data, $this->datamodel, $this->functions, $name); + return $view; + } + + /** + * Modulausführung starten + * + * Die eigentliche Ausführung des Moduls wird gestartet. + * Es werden Controller und View erzeugt und der Standardablauf + * ausgeführt. + * Einhakpunkte sind: + * + * $modul->prepare Vorbereitende Aktionen für das Modul + * $controller->common vor allen anderen Aktionen + * $controller->alternate wird ausgeführt, wenn $controller->common FALSE zurückgibt + * $modul->clean_up Aufräumen nach allen Aktionen + * + * @pattern "Template Method" + */ + final public function start_execution() { + $modul_name = str_replace('_modul', '', get_class($this)); + + // Modul vorbereiten + $this->prepare(); + + $action = $this->cap['action']; + $params = $this->cap['param']; + + // Standardablauf ausführen + $this->controller = $this->create_controller($modul_name); + $this->model = $this->create_model($modul_name); + + try { + $this->controller->common($params); + if ( !isset($action) OR !method_exists($this->controller, $action) ) { + $action = 'defaultAction'; + } + $this->controller->$action($params); + + /** + * Ãœbergangsweise + */ + $response = $this->controller->get_response(); + $data = $response->get('data'); + $layout = $response->get('layout'); + + $this->registry->set('subview', $response->get('subview')); + + $this->view = $this->create_view($modul_name, $data); + $this->contents = $this->view->render_layout($layout); + $this->output_contents(); + /** + * Ende Ãœbergangsweise Code + */ + + + foreach( $this->controller->get_response() as $response ) { + $view = $this->factory->create_view($response->get_type()); + /** + * Der folgende Code muss von view übernommen und + * mit $view->execute($response) ausgeführt werden + + $data = $response->get('data'); + $layout = $response->get('layout'); + + $this->registry->set('subview', $response->get('subview')); + + $this->view = $this->create_view($modul_name, $data); + $this->contents = $this->view->render_layout($layout); + $this->output_contents(); + + */ + $view->execute($response); + } + } catch ( Exception $e ) { + $this->controller->alternate($e); + } + $this->clean_up(); + + /* + * alte funktion + } + public function start_execution() { + $modul_name = str_replace('_modul', '', get_class($this)); + + // Modul vorbereiten + $this->prepare(); + + $action = $this->cap['action']; + $params = $this->cap['param']; + + // Standardablauf ausführen + $this->controller = $this->create_controller($modul_name); + $this->model = $this->create_model($modul_name); + + if ( $this->controller->common() ) { + if ( !isset($action) OR !method_exists($this->controller, $action) ) { + $action = 'defaultAction'; + } + $this->controller->$action($params); + $response = $this->controller->get_response(); + $data = $response->get('data'); + $layout = $response->get('layout'); + + $this->registry->set('subview', $response->get('subview')); + + $this->view = $this->create_view($modul_name, $data); + $this->contents = $this->view->render_layout($layout); + } else { + $this->controller->alternate(); + } + $this->output_contents(); + $this->clean_up(); + */ + } + + /** + * Vorbereitung des Moduls (Hook) + * + * Das Ergebnis wird nicht geprüft. + */ + protected function prepare() { + return; + } + + /** + * Ausgabe der Daten + */ + public function output_contents() { + echo $this->contents; + } + + /** + * Aufräumfunktion (Hook) + * + * $modul->clean_up wird nach allen anderen Funktionen im Modulkontext + * aufgerufen und bietet so einen letzten Einhakpunkt für Aktionen. + * + * Das Ergebnis wird nicht geprüft. + */ + protected function clean_up() { + return; + } +} +?> diff --git a/fl/mvc/view.php b/fl/mvc/view.php new file mode 100644 index 0000000..5409e50 --- /dev/null +++ b/fl/mvc/view.php @@ -0,0 +1,244 @@ +datamodel = $data_access; + $this->functions = $functions; + $this->factory = $functions->factory; + + $this->data = $this->factory->get_structure('view', $data); + + $registry = fl_registry::getInstance(); + $this->cap = $registry->get('request', 'route'); + $this->subview = $registry->get('subview'); + + $this->modulepath = $registry->get('path', 'module'); + $this->apppath = $registry->get('path', 'app'); + $this->elementpath = $registry->get('path', 'elements'); + $this->layoutpath = $registry->get('path', 'layouts'); + + $this->headers = $registry->get('config', 'headers'); + + $model = $this->factory->get_model($model_name); + $this->translator = $model->translator; + } + + /** + * Ruft das Template auf + * + * @param string $layout + * @return string + */ + public function render_layout($layout) { + if ( strpos($layout, '/') === FALSE ) { + $path = $this->modulepath . $this->cap['controller'] . '/layouts/'; + } else { + list($prefix, $layout) = explode('/', $layout, 2); + if ( $prefix == 'comon' ) { + $path = $this->layoutpath; + } else { + $path = $this->modulepath . $prefix . '/layouts/'; + } + } + + /** + * Content-Type setzen, wenn Header noch nicht gesendet + */ + if ( !headers_sent() ) { + header('Content-Type: ' . $this->headers['content-type'] . + '; charset=' . $this->headers['charset'] ); + } + + ob_start(); + require_once $path . $layout . '.php'; + $template = ob_get_contents(); + ob_end_clean(); + + return $template; + } + + /** + * Sucht den zur Action passenden Unterview heraus. + */ + protected function get_sub_view() { + require_once($this->modulepath . $this->cap['controller'] . '/views/' . $this->subview . '.php'); + } + + /** + * Ein Seitenelement holen + * + * Es wird ein vordefinierter HTML-Baustein geholt. + * Er steht allen Seitenbereichen zu Verfügung. + * Variablen können als Assoziatives Array übergeben werden. + * Sonstigen Variablen sind meist nicht + * verfügbar. + * + * @param string $name Dateiname (ohne Endung) des Elements. + * @param array $vars Assoziatives Array mit Variablen fuer das Element. + */ + protected function get_element($name, array $vars = array() ) { + require_once $this->elementpath . $name . '.php'; + } + + /** + * Teilbereich eines Subview holen + * + * @param string $name Name des Teilbereichs + */ + protected function get_partial($name, $forgiving=FALSE) { + $file = $this->modulepath . $this->cap['controller'] . '/partials/' . $name . '.php'; + + if ( $forgiving AND !file_exists($file) ) { + return; + } else { + require_once $file; + } + } + + /** + * Gibt die Flash-Nachricht zurück + * + * @param string $namespace + * @return string + */ + protected function render_flash($namespace='') { + $html = ''; + + $messages = $this->functions->flash->get_messages($namespace); + foreach( $messages as $message ) { + $html .= '

'.$message['msg'].'

'.PHP_EOL; + } + $this->functions->flash->clear_messages($namespace); + + return $html; + } + + /** + * Seitentitel ausgeben + * + * @return string + */ + protected function get_site_title() { + if ( !defined('SEITENTITEL') ) { + $result = $this->datamodel->retrieve('optionen', '*', "optionname='seitentitel'", '', '1'); + #define('SEITENTITEL', $result['value']); + $title = $result[0]['value']; + } else { + $title = SEITENTITEL; + } + + echo $title; + return; + } + + /** + * Wrapper fuer Datenobjekt + */ + protected function get($field, $type='string', $source=NULL, $raw=FALSE, $default='') { + if ( $source instanceof data_structure) { + return $source->get($field, $type, $raw, $default); + } + + $this->data->set_raw_output($raw); + $former_default = $this->data->set_default($default); + + $value = $this->data->get($field, $type); + + $this->data->set_default($former_default); + return $value; + } + + /** + * Wrapper fuer Datenobjekt + */ + protected function say($field, $type='string', $source=NULL, $raw_output=FALSE, $default='') { + echo $this->get($field, $type, $source, $raw_output, $default); + } + + /** + * Datenobjekt zurueckgeben + * + * @return view_data + */ + public function get_data_object() { + return $this->data; + } + + /** + * Ãœbersetzten Text ausgeben + * + * Es wird ein Text zurückgegeben, der entweder eine Ãœbersetzung + * des übergebenen Textes ist oder der übergebene Text selbst. + * + * @todo Achtung: Funktion ist auch in fl/model.php definiert. Sollte besser nur dort sein. Entwurf verbessern! + * @param string $text + * @param string $lang + * @return string + */ + protected function translate($text, $lang=LANG) { + if ( is_object($this->translator) ) { + $translation = $this->translator->get($text, $lang); + } else { + $translation = $text; + } + + return $translation; + } + + /** + * URL zur aktuellen Seite ausgeben + * + * @todo Routen so erweitern, das die aktuelle URL ausgegeben werden kann. + */ + protected function current_url() { + $registry =& fl_registry::getInstance(); + $cap = $registry->get('request', 'route'); + $url = 'http://'.$_SERVER['HTTP_HOST'].'/'.$cap['controller'].'/'.$cap['action'].'/'.$cap['param']; + return $url; + } +} +?> diff --git a/fl/tools/autoload.php b/fl/tools/autoload.php new file mode 100644 index 0000000..685fe83 --- /dev/null +++ b/fl/tools/autoload.php @@ -0,0 +1,40 @@ +$id, + 'name'=>$name + ); + } + + return $array; + } + + /** + * Dropdown-Array zu String machen + * + * @param array $data + * @return string + */ + public static function dropdown_array_to_string($data) { + foreach( $data as $value) { + $string[] = $value['id'].'='.$value['name']; + } + + $string = implode(',', $string); + + return $string; + } +} diff --git a/fl/tools/factory.php b/fl/tools/factory.php new file mode 100644 index 0000000..68a6a35 --- /dev/null +++ b/fl/tools/factory.php @@ -0,0 +1,318 @@ +registry = fl_registry::getInstance(); + $this->structures = new fl_data_structures(); + + $lang = $this->registry->get('config', 'lang'); + $this->inflector = new fl_inflector($lang['application']); + } + + /** + * Datenzugriff setzen + * + * @param data_access $data_access + */ + public function set_data_access(data_access $data_access) { + $this->data_access = $data_access; + } + + /** + * Eine Federleicht-interne Klasse erzeugen und zurückgeben + * + * @todo verbessern, indem die verschiedenen Klassen mit den entsprechenden Parametern versorgt werden oder an passende Methoden deligiert wird... + * @param string $class_name + * @return mixed + */ + public function create($class_name) { + $class = "fl_{$class_name}"; + return new $class(); + } + + /** + * Weiteres Model holen + * + * Nach Möglichkeit wird das Model aus der Registry geholt. + * @pattern IdentityMap + * + * @throws LogicException Wenn keine Datenzugriffsklasse gesetzt wurde. + * + * @param string $modul Name des Moduls, aus dem das Model geholt wird. + * @return fl_model + */ + public function get_model($modul) { + if ( $this->registry->get('loaded_model_'.$modul) === FALSE ) { + if ( $this->data_access == null ) { + throw new LogicException('Der Factory ist keine Datenzugriffsklasse bekannt: Mit set_data_access(data_access) setzen!'); + } + + $this->load_module($modul); + + $model_name = 'app_' . $modul . '_model'; + $get_model = new $model_name( + $this->data_access, + $this, + (string) $this->registry->get('path', 'module')); + + $this->registry->set('loaded_model_'.$modul, $get_model); + } + + return $this->registry->get('loaded_model_'.$modul); + } + + /** + * Klasse holen + * + * @param string $class + * @param array $options (dynamic) + * @return object + */ + public function get_class($class) { + if ( strpos($class, '/') === false) { + throw new InvalidArgumentException('Klassenname muss in der Form modul/class angegeben werden.'); + } else { + list($modul, $class_name) = explode('/', $class, 2); + } + + $this->load_class($modul, $class_name); + + $instance = new $class_name(); + if ( func_num_args() > 1 ) { + $args = func_get_args(); + array_shift($args); + $options = array_values($args); + + $instance->set_options($options); + } + + return $instance; + } + + /** + * Activerecord-Klasse holen + * + * Nach Möglichkeit wird der Record aus der Registry geholt. + * @pattern IdentityMap + * + * @throws InvalidArgumentException Wenn der erste Parameter keinen Slash enthält + * + * @param string $class + * @param int $id + * @param array $data + * @return fl_data_structures_activerecord + */ + public function get_ar_class($class, $id = 0, array $data = array()) { + if ( strpos($class, '/') === false) { + throw new InvalidArgumentException('Klassenname muss in der Form modul/class angegeben werden.'); + } else { + list($modul, $class_name) = explode('/', $class, 2); + } + + $this->load_structure('activerecord'); + $this->load_class($modul, $class_name); + + $data = (array) $data; + if (!empty($data)) { + $loaded = true; + } else { + $loaded = false; + $data += array('id'=>$id); + } + + if ( $this->is_structure($modul, $class_name) ) { + $data_structure = $this->get_structure($modul.'/'.$class_name, $data); + } else { + $data_structure = $this->get_structure('data', $data); + } + + $identifier = "{$class_name}_{$id}"; + + if ( !$this->registry->is_set('loaded_record_'.$identifier) ) { + $instance = new $class_name( + $this->data_access, + $this->inflector->plural($class_name), + $id, + $data_structure, + $loaded + ); + + $this->registry->set('loaded_record_'.$identifier, $instance); + } + + return $this->registry->get('loaded_record_'.$identifier); + } + + /** + * Datenstruktur holen + * + * @param string $wanted_structure + * @param array $data + * @return data_wrapper + */ + public function get_structure($wanted_structure, $data = null) { + return $this->structures->get($wanted_structure, $data); + } + + /** + * Helfermodul holen + * + * @param string $wanted_helper + * Weitere Parameter werden übernommen und an den Konstruktor weitergegeben. + * + * @return object + */ + public function get_helper($wanted_helper) { + $this->load_helper($wanted_helper); + + switch ( func_num_args() ) { + case 3: + $f1 = func_get_arg(1); + $f2 = func_get_arg(2); + $helper = new $wanted_helper($f1, $f2); + break; + + case 2: + $f1 = func_get_arg(1); + $helper = new $wanted_helper($f1); + break; + + case 1: + default: + $helper = new $wanted_helper(); + } + + return $helper; + } + + + /** + * ############# Funktionen zum Einlesen der entsprechenden Dateien ###### + */ + + + /** + * Datenstruktur einlesen + * + * @param string $wanted_structure + */ + public function load_structure($wanted_structure) { + if ( strpos($wanted_structure, '/') === false ) { + $this->structures->load_structure($this->structures->built_in, $wanted_structure); + } + } + + /** + * Klassendatei einlesen + * + * @param string $modul + * @param string $class + */ + public function load_class($modul, $class) { + require_once $this->registry->get('path', 'module') . $modul . '/classes/'.$class.'.php'; + } + + /** + * Aufruf eines Helfermodul + * + * Der Quellcode eines namentlich benannten + * Helfermoduls wird eingelesen. + * + * @throws OutOfRangeException Wenn die gewünschte Helperklasse nicht existiert + * + * @param string $wanted Name des gewünschten Helfermoduls + * @return boolean + */ + public function load_helper($wanted) { + if ( !in_array( $wanted, $this->registry->get('helpers') ) ) { + throw new OutOfRangeException("Helperklasse {$wanted} nicht gefunden"); + } + + include_once $this->registry->get('path', 'helper') . $wanted . '.php'; + + return TRUE; + } + + /** + * Moduldatei einlesen + * + * @throws OutOfRangeException Wenn die passende Moduldatei nicht existiert + * @param string $modul + */ + public function load_module($modul) { + $modul_path = $this->registry->get('path', 'module') . $modul . '/model.php'; + + if ( !in_array($modul, $this->registry->get('modules')) ) { + $common_path = $this->registry->get('path', 'module') . 'common/models/'.$modul.'.php'; + + if ( file_exists( $common_path ) ) { + $modul_path = $common_path; + } else { + throw new OutOfRangeException("Modul {$modul} wurde nicht gefunden"); + } + } + + require_once $modul_path; + } + + + + /** + * ########## Funktionen, die auf Existenz der entsprechenden Dateien #### + */ + + + /** + * Pruefung, ob Datenstruktur existiert + * + * @param string $modul + * @param string $class + * @return boolean + */ + public function is_structure($modul, $class) { + return $this->structures->exists($modul, $class); + } + + /** + * ########## interne Funktionen ######################################### + */ + + /** + * Klassenidentifikator parsen + * + * @param string $class + * @return array + * @access private + */ + protected function parse_class_name($class) { + $common = 'common'; + $builtin = 'builtin'; + + if ( strpos($class, '/') === false) { + $result = array($common, $class); + } else { + $result = explode('/', $class, 2); + } + + return $result; + } +} diff --git a/fl/tools/flash.php b/fl/tools/flash.php new file mode 100644 index 0000000..fa53b08 --- /dev/null +++ b/fl/tools/flash.php @@ -0,0 +1,214 @@ + + * @version 0.2 + * @license MIT-Style + */ +class fl_flash { + /** + * message storage + * + * messages are stored in an array of the following form: + * [namespace][][msg] + * [type] + * + * the array itself is an associative array of namespaces. + * [namespace] = array(); + * + * Each namespaces has an array which contain the actual + * message. + * + * Every message is itself an array with the following keys + * [msg] message-text + * [type] message-type + * + * The type could be used as css-class (at least I do). + * + * types and namespaces are saved lowercase only + */ + private $messages; + + /** + * default message type + */ + private $default_type; + + /** + * default namespace + */ + private $default_namespace; + + /** + * constructor + */ + public function __construct($type='', $namespace='') { + $this->set_default_type($type); + $this->set_default_namespace($namespace); + + $this->messages = $this->load_all_messages(); + } + + /** + * destructor + */ + public function __destruct() { + return $this->save_all_messages(); + } + + /** + * set default message type + * + * @param string $type + * @return bool + */ + public function set_default_type($type='') { + $set = FALSE; + $type = ( empty($type) )? + 'notice': + $type; + + $this->default_type = strtolower($type); + $set = TRUE; + + return $set; + } + + /** + * Set default namespace + * + * @param string $namespace + * @return bool + */ + public function set_default_namespace($namespace='') { + $set = FALSE; + $namespace = ( empty($namespace) )? + 'global': + $namespace; + + $this->default_namespace = strtolower($namespace); + $set = TRUE; + + return $set; + } + + /** + * add a message + * + * @param string $message + * @param string $namespace + * @param string $type + * @return bool + */ + public function add_message($message='', $namespace='', $type='') { + $added = FALSE; + + if ($message == '') return $added; + if ($namespace == '') $namespace = $this->default_namespace; + if ($type == '') $type = $this->default_type; + + if (!isset($this->messages[$namespace])) { + $this->messages[$namespace] = array(); + } + + $msg = array( + 'msg'=>$message, + 'type'=>$type + ); + + $this->messages[$namespace][] = $msg; + $added = TRUE; + + return $added; + } + + /** + * return messages of a certain namespace + * + * @param string $namespace + * @return array + */ + public function get_messages($namespace='') { + $messages = array(); + + if ($namespace == '') $namespace = $this->default_namespace; + + if ( isset($this->messages[$namespace]) ) { + $messages = $this->messages[$namespace]; + } + + return $messages; + } + + /** + * clear messages of a certain namespace + * + * @param string $namespace + * @return bool + */ + public function clear_messages($namespace='') { + $cleared = FALSE; + + if ($namespace == '') $namespace = $this->default_namespace; + + $this->messages[$namespace] = array(); + $cleared = TRUE; + + return $cleared; + } + + + /** + * Invoke saving manually + * + * @return bool + */ + public function save_messages() { + return $this->save_all_messages(); + } + + /* == INTERNALLY USED == */ + + /** + * save serialized message-array to SESSION + * + * @todo check save success reliable + * @return bool + */ + private function save_all_messages() { + $saved = FALSE; + + $msg = serialize($this->messages); + + $_SESSION['flash_messages'] = $msg; + $saved = TRUE; + + session_write_close(); + + return $saved; + } + + /** + * load and unserialize messages from SESSION + * + * @return array + */ + private function load_all_messages() { + $msg = array(); + + if ( isset($_SESSION['flash_messages'] )) { + $msg = unserialize( $_SESSION['flash_messages'] ); + } + + return $msg; + } +} diff --git a/fl/tools/functions.php b/fl/tools/functions.php new file mode 100644 index 0000000..9f65043 --- /dev/null +++ b/fl/tools/functions.php @@ -0,0 +1,50 @@ +factory = new fl_factory(); + } + + /** + * Datenzugriff setzen + * + * @param data_access $data_access + */ + public function set_data_access(data_access $data_access) { + $this->factory->set_data_access($data_access); + } + + /** + * Flashnachrichten starten + */ + public function start_flash() { + $this->flash = new fl_flash(); + } + + /** + * Federleicht anhalten + */ + public function stop($message='') { + ob_flush(); + echo $message; + exit(); + } +} +?> diff --git a/fl/tools/inflector.php b/fl/tools/inflector.php new file mode 100644 index 0000000..35d9131 --- /dev/null +++ b/fl/tools/inflector.php @@ -0,0 +1,189 @@ + + * @version 0.1 + */ +class fl_inflector { + /** + * Speicher für Ersetzungsregeln + */ + var $plural = array(); + var $singular = array(); + var $uncountable = array(); + var $irregular = array(); + + /** + * Konstruktor + */ + function __construct($lang = null) { + switch ( $lang ) { + case 'de': + $this->plural = array( + '/^([a-z]*)(ung|heit|schaft|ion)$/i'=>'\1\2en', + '/^([a-z]*)(probe)$/i'=>'\1\2n', + '/^([a-z]*[^aoieukgh])$/i' =>'\1e', + ); + + $this->singular = array( + '/^([a-z]*)(ung|heit|schaft|ion)en$/i'=>'\1\2', + '/^([a-z]*)(probe)n$/i'=>'\1\2', + '/^([a-z]*)e/i' => '\1', + ); + + $this->uncountable = array( + 'daten', + 'bankdaten', + 'cover', + 'musiktitel', + 'titel', + ); + + $this->irregular = array( + 'account' => 'accounts', + 'land' => 'laender', + ); + break; + + case 'en': + default: + $this->plural = array( + '/(quiz)$/i' => '\1zes', + '/^(ox)$/i' => '\1en', + '/([m|l])ouse$/i' => '\1ice', + '/(matr|vert|ind)ix|ex$/i' => '\1ices', + '/(x|ch|ss|sh)$/i' => '\1es', + '/([^aeiouy]|qu)ies$/i' => '\1y', + '/([^aeiouy]|qu)y$/i' => '\1ies', + '/(hive)$/i' => '\1s', + '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', + '/sis$/i' => 'ses', + '/([ti])um$/i' => '\1a', + '/(buffal|tomat)o$/i' => '\1oes', + '/(bu)s$/i' => '\1ses', + '/(alias|status)/i'=> '\1es', + '/(octop|vir)us$/i'=> '\1i', + '/(ax|test)is$/i'=> '\1es', + '/s$/i'=> 's', + '/$/'=> 's' + ); + + $this->singular = array ( + '/(quiz)zes$/i' => '\\1', + '/(matr)ices$/i' => '\\1ix', + '/(vert|ind)ices$/i' => '\\1ex', + '/^(ox)en/i' => '\\1', + '/(alias|status)es$/i' => '\\1', + '/([octop|vir])i$/i' => '\\1us', + '/(cris|ax|test)es$/i' => '\\1is', + '/(shoe)s$/i' => '\\1', + '/(o)es$/i' => '\\1', + '/(bus)es$/i' => '\\1', + '/([m|l])ice$/i' => '\\1ouse', + '/(x|ch|ss|sh)es$/i' => '\\1', + '/(m)ovies$/i' => '\\1ovie', + '/(s)eries$/i' => '\\1eries', + '/([^aeiouy]|qu)ies$/i' => '\\1y', + '/([lr])ves$/i' => '\\1f', + '/(tive)s$/i' => '\\1', + '/(hive)s$/i' => '\\1', + '/([^f])ves$/i' => '\\1fe', + '/(^analy)ses$/i' => '\\1sis', + '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\\1\\2sis', + '/([ti])a$/i' => '\\1um', + '/(n)ews$/i' => '\\1ews', + '/s$/i' => '', + ); + + $this->uncountable = array( + 'equipment', + 'information', + 'rice', + 'money', + 'species', + 'series', + 'fish', + 'sheep' + ); + + $this->irregular = array( + 'person' => 'people', + 'man' => 'men', + 'child' => 'children', + 'sex' => 'sexes', + 'move' => 'moves' + ); + break; + } + } + + /** + * Bildung der Pluralform eines Wortes + * + * @param string $word + * @return string Pluralform + */ + function plural($word) { + $plural = $this->plural; + $uncountable = $this->uncountable; + $irregular = $this->irregular; + + $lowercased_word = strtolower($word); + + foreach ($uncountable as $_uncountable){ + if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){ + return $word; + } + } + + foreach ($irregular as $_plural=> $_singular){ + if (preg_match('/('.$_plural.')$/i', $word, $arr)) { + return preg_replace('/('.$_plural.')$/i', substr($arr[0],0,1).substr($_singular,1), $word); + } + } + + foreach ($plural as $rule => $replacement) { + if (preg_match($rule, $word)) { + return preg_replace($rule, $replacement, $word); + } + } + + return false; + } + + /** + * Bildung der Singularform eines Wortes + * + * @param string $word + * @return string Singularform + */ + function singular($word) { + $singular = $this->singular; + $uncountable = $this->uncountable; + $irregular = $this->irregular; + + $lowercased_word = strtolower($word); + foreach ($uncountable as $_uncountable){ + if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){ + return $word; + } + } + + foreach ($irregular as $_plural=> $_singular){ + if (preg_match('/('.$_singular.')$/i', $word, $arr)) { + return preg_replace('/('.$_singular.')$/i', substr($arr[0],0,1).substr($_plural,1), $word); + } + } + + foreach ($singular as $rule => $replacement) { + if (preg_match($rule, $word)) { + return preg_replace($rule, $replacement, $word); + } + } + + return $word; + } +} diff --git a/fl/tools/registry.php b/fl/tools/registry.php new file mode 100644 index 0000000..ce4da01 --- /dev/null +++ b/fl/tools/registry.php @@ -0,0 +1,98 @@ +values = array(); + } + + private function __clone() { + } + + /** + * Instanz holen + */ + public static function getInstance() { + if ( self::$instance === null ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Allgemeines GET + * + * Der interne Variablenspeicher wird erst nach dem Schlüssel durchsucht. + * Wenn weiterhin ein Index gegeben ist, wird versucht, die Variable als + * Array oder Objekt zu verwenden und so den Variableninhalt direkt + * zurückzugeben. + * + * Wenn der angefragte Variableninhalt nicht gefunden wurde, wird FALSE + * zurückgegeben. + * + * @param string $key + * @paran string $index + * @return mixed + */ + public function get($key, $index = null) { + $key = (string) $key; + $methodcall = 'get_'.$index; + + if ( isset($this->values[$key]) ) { + $value = $this->values[$key]; + } else { + $value = FALSE; + } + + if ( $index !== null ) { + if ( is_array($value) AND isset($value[$index]) ) { + $value = $value[$index]; + } elseif ( is_object($value) AND method_exists($value, $methodcall) ) { + $value = $value->$methodcall(); + } elseif ( is_object($value) AND isset($value->$index) ) { + $value = $value->$index; + } else { + $value = FALSE; + } + } + + return $value; + } + + /** + * Allgemeines SET + * + * @param string $key + * @param mixed $value + */ + public function set($key, $value) { + $key = (string) $key; + + $this->values[$key] = $value; + } + + /** + * Prüfung, ob Wert existiert + * + */ + public function is_set($key) { + $available = false; + + if ( isset($this->values[$key]) ) { + $available = true; + } + + return $available; + } +} diff --git a/fl/tools/responder.php b/fl/tools/responder.php new file mode 100644 index 0000000..c3607ea --- /dev/null +++ b/fl/tools/responder.php @@ -0,0 +1,103 @@ +response_list[] = new $class_name(); + + $response_key = count($this->response_list) - 1; + $this->set_current_response($response_key); + + return $response_key; + } + + /** + * Aktuell zu bearbeitende Response setzen + * + * @param int $response_key + * @throws OutOfBoundsException + */ + public function set_current_response($response_key) { + $previous_key = $this->key(); + $this->key = $response_key; + + if ( ! $this->valid() ) { + $this->key = $previous_key; + throw new OutOfBoundsException("Response {$response_key} ist nicht im Responder vorhanden"); + } + } + + /** + * Interface data_wrapper + * + * weil die Response-Objekte dieses Interface implementieren + */ + public function set($key, $value) { + $response = $this->current(); + $response->set($key, $value); + } + public function get($key) { + $response = $this->current(); + return $response->get($key); + } + public function say($key) { + $response = $this->current(); + $response->say($key); + } + + public function set_data(array $data) { + $response = $this->current(); + $response->set_data($data); + } + public function is_set($key) { + $response = $this->current(); + return $response->is_set($key); + } + public function remove($key) { + $response = $this->current(); + $response->remove($key); + } + /** Ende des Interface data_wrapper */ + + /** + * Interface Iterator + * + * Wird implementiert, um in fl_modul::start_execution() die verschiedenen + * Rückgaben einzeln zu bearbeiten. + */ + public function ¤t() { + return $this->response_list[$this->key()]; + } + public function key() { + return $this->key; + } + public function next() { + $this->key++; + } + public function rewind() { + $this->key = 0; + } + public function valid() { + return $this->key < count($this->response_list); + } + /** Ende des Interface Interface */ +} diff --git a/fl/web_start.php b/fl/web_start.php new file mode 100644 index 0000000..85a0033 --- /dev/null +++ b/fl/web_start.php @@ -0,0 +1,72 @@ + + * @version 0.2 + * @license BSD-License + */ +/** + * Gesamtzeitmessung + */ +ini_set('precision', '16'); +function getmicrotime() { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); +} +$start = getmicrotime(); + +/** + * Federleicht-Objekt holen + */ +require_once 'federleicht.php'; + +/** + * Der Name des Objekts wird nur in dieser Datei genannt + */ +$federleicht = new federleicht($_SERVER['REQUEST_URI']); + +/** + * Get fl framework object + * + * @return federleicht + * @deprecated + */ +function get_fl() { + global $federleicht; + + return $federleicht; +} + +function needs($wanted) { + $fl_framework = get_fl(); + $fl_framework->functions->needs($wanted); + + return TRUE; +} + +$federleicht->start(); + +$federleicht->functions->stop(); + + + +/** + * Auswertung der Gesamtzeitmessung + */ +$end = getmicrotime(); +$shit = $federleicht->functions->factory->get_helper( + 'var_analyze', + 'Allgemein', 'index.php' +); +$shit->timer($start, $end, -1); +$shit->say('Anzahl der Datenbankabfragen: ' . ( $federleicht->datamodel->query_count ) . ''); +$shit->sv($federleicht->datamodel->allSQL, 'Datenbankabfragen'); + +trigger_error('end'); +$federleicht->functions->stop(); diff --git a/index.php b/index.php new file mode 100644 index 0000000..9bb073a --- /dev/null +++ b/index.php @@ -0,0 +1,2 @@ +#hoverNav{ left: 0;} +#hoverNav a{ outline: none;} + +#prevLink, #nextLink{ + width: 49%; + height: 100%; + background: transparent url(../img/lightbox/system/blank.gif) no-repeat; /* Trick IE into showing hover */ + display: block; + } +#prevLink { left: 0; float: left;} +#nextLink { right: 0; float: right;} +#prevLink:hover, #prevLink:visited:hover { background: url(../img/lightbox/system/prevlabel.gif) left 15% no-repeat; } +#nextLink:hover, #nextLink:visited:hover { background: url(../img/lightbox/system/nextlabel.gif) right 15% no-repeat; } + + +#imageDataContainer{ + font: 11px Verdana, Helvetica, sans-serif; + background-color: #FFF; + margin: 0 auto; + line-height: 1.4em; + } + +#imageData{ + padding:6px 0 0 20px; + color:#7F7F7F; + } +#imageData #imageDetails{ width: 70%; float: left; text-align: left; } +#imageData #caption{ font-weight: none; } +#imageData #numberDisplay{ font-size:9px; display: block; clear: left; padding-bottom: 1.0em; } +#imageData #bottomNavClose{ width: 66px; float: right; padding-bottom: 0.7em; } + +#overlay{ + position: absolute; + top: 0; + left: 0; + z-index: 90; + width: 100%; + height: 500px; + background-color: #000; + filter:alpha(opacity=60); + -moz-opacity: 0.6; + opacity: 0.6; + } + + +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; + } + +* html>body .clearfix { + display: inline-block; + width: 100%; + } + +* html .clearfix { + /* Hides from IE-mac \*/ + height: 1%; + /* End hide from IE-mac */ + } + \ No newline at end of file diff --git a/public/css/print.css b/public/css/print.css new file mode 100644 index 0000000..0109130 --- /dev/null +++ b/public/css/print.css @@ -0,0 +1,37 @@ +html,address,blockquote,body,div,dl,dt,dd,fieldset,form,h1,h2,h3,h4,h5,h6,ol,p,ul,li,center,hr,pre,table,tr,td,th,thead,tbody,tfoot,caption { + font-family:inherit; font-style:normal; font-weight:normal; + font-variant:normal; font-size:inherit; line-height:inherit; + text-align:left; text-decoration:none; padding:0; margin:0; + float:none; border:0px; display:block; cursor:default; } +span,a,img,abbr,code,em,strong,b,i,var,tt,kbd,samp,small,sub,sup { + font:inherit; background:transparent; padding:0; margin:0; + color:inherit; display:inline; float:none; border:0; } +textarea,legend,label,button,input,object,select { font:inherit; margin:0; padding:0; } + +li { display:list-item; } + +table { display:table; border-spacing:0; border-collapse:collapse; } +tr { display:table-row; } +th,td { display:table-cell; } +thead { display:table-header-group; } +tbody { display:table-row-group; } +tfoot { display:table-footer-group; } +caption { display:table-caption; } +colgroup { display:table-column-group; } +col { display:table-column; } + +head { display:none; } + +/* Optionales */ +html { font-family:Verdana, 'Lucida Grande', Geneva, Lucida, Arial, Helvetica, sans-serif; font-size:10pt; line-height:15pt; color:#000; } +ul li { list-style-type:disc; } +ol li { list-style-type:decimal; } + +/* unwichtiges verbergen */ +body { background:none; } +#navigation, .kopfbild, #buttons, #internenavi { display:none; } + +/* wichtiges richtig darstellen */ +h3 { font-weight:bold; margin:12pt 0 0 0; } +h3 img { margin:-12pt 0 0 0; } +p { margin:0 0 6pt 0; } \ No newline at end of file diff --git a/public/css/screen.css b/public/css/screen.css new file mode 100644 index 0000000..c490eba --- /dev/null +++ b/public/css/screen.css @@ -0,0 +1,180 @@ +html,address,blockquote,body,div,dl,dt,dd,fieldset,form,h1,h2,h3,h4,h5,h6,ol,p,ul,li,center,hr,pre,table,tr,td,th,thead,tbody,tfoot { + font-family:inherit; font-style:normal; font-weight:normal; + font-variant:normal; font-size:inherit; line-height:inherit; + text-align:left; text-decoration:none; padding:0; margin:0; + float:none; border:0px; display:block; cursor:default; } +span,a,img,abbr,code,em,strong,b,i,var,tt,kbd,samp,small,sub,sup,caption { + font:inherit; background:transparent; padding:0; margin:0; + color:inherit; display:inline; float:none; border:0; } +textarea,legend,label,button,input,object,select { font:inherit; margin:0; padding:0; } + +li { display:list-item; } + +table { display:table; border-spacing:0; border-collapse:collapse; } +tr { display:table-row; } +th,td { display:table-cell; } +thead { display:table-header-group; } +tbody { display:table-row-group; } +tfoot { display:table-footer-group; } +caption { display:table-caption; } +colgroup { display:table-column-group; } +col { display:table-column; } + +head { display:none; } + +/* { Optionales */ +html { font-family:Verdana, 'Lucida Grande', Geneva, Lucida, Arial, Helvetica, sans-serif; font-size:11px; line-height:18px; color:#808080; } +a:link, a:visited, a:hover, a:active { cursor:pointer; } +input, textarea { cursor:auto; } +ul li { list-style-type:square; } +ol li { list-style-type:decimal; } +/* } */ + +/* { Allgemeines Layout */ +#wrapper { width:927px; margin:0 auto; } +#kopf { margin:18px 0 0 0; position:relative; height:186px; z-index:1; } +#kopf h1 { position:relative; top:29px; left:696px; width:173px; height:103px; z-index:2; } +#kopf img.kopfbild { position:absolute; top:0; left:0; z-index:2; } +#kopf #navigation { position:absolute; top:165px; left:134px; width:515px; height:32px; z-index:3; line-height:28px; } +#kopf #navigation p span.separator { float:left; color:#c8d200; padding:0 4px; } +#kopf #navigation a { float:left; display:block; padding:0 4px; } + +#kundennavi { position:absolute; top:24px; left:523px; z-index:4; width:150px; } +#kundennavi p {padding:5px 0 0 0;} + +#subnavigation {width:113px; position:relative; top:-27px; left:9px; z-index:3; } +#subnavigation p {padding:2px 0 2px 0; border-bottom:1px #9A9A9A dotted;} + +#content { position:relative; z-index:3; } + +#haftungsausschluss {clear:both; width:760px; padding:0 80px; } + +#unten { clear:both; padding:50px 0 0 145px; height:33px; } +#unten p span.separator { color:#FFF; padding:0 3px; } +/* } */ + +/** Layout-details */ +.description { + padding-left:10px; +} + +/* { Links */ +a:link, +a:visited { text-decoration:none; color:#808080;} +a:focus, +a:hover { text-decoration:none; color:#c8d200; } +a:active { text-decoration:none; color:#c8d200; } + +#navigation a:link, +#navigation a:visited { text-decoration:none; color:#fff; } +#navigation a:focus, +#navigation a:hover { text-decoration:none; color:#c8d200; } +#navigation a:active { text-decoration:none; color:#c8d200; } + +a.symbol, +#kundennavi a, +#subnavigation a { display:block; padding:0 0 3px 21px; background:url(../img/icon_pfeil_off.gif) 0 2px no-repeat; line-height:22px; height:22px; } + +a.symbol:focus, +a.symbol:hover, +a.symbol:active, +#kundennavi a:focus, +#kundennavi a:hover, +#kundennavi a:active, +#subnavigation a:focus, +#subnavigation a:hover, +#subnavigation a:active { font-weight:bold; background:url(../img/icon_pfeil_on.gif) 0 2px no-repeat; } + +#subnavigation a:link.aktiv, +#subnavigation a:visited.aktiv {color:#c8d200; font-weight:bold; background:url(../img/icon_pfeil_on.gif) 0 2px no-repeat; } + +#unten a:link, #unten a:visited {} +#unten a:focus, #unten a:hover, #unten a:active, #news_spalte a:focus, #news_spalte a:hover, #news_spalte a:active { color:#fff; } +/* } */ + +/* Navigation */ +body.about #navigation a.about, +body.design #navigation a.design, +body.coding #navigation a.coding, +body.portfolio #navigation a.portfolio { color:#c8d200; } + +/* Kundennavi */ +body.start #kundennavi a.pages { color:#c8d200; } +body.contact #kundennavi a.contact, +body.start #kundennavi a.start, +body.sitemap #kundennavi a.sitemap { font-weight:bold; color:#c8d200; background:url(../img/icon_pfeil_on.gif) 0 2px no-repeat; } + + + +/* { Klassen */ +.hidden, .print-info { display:none; } +.required { padding:0 5px; color:#c8d200; } +.aktiv { color:#c8d200; font-weight:bold; padding: 3px 0px; } +/* } */ + +/* { Farben und Hintergründe */ +body { background-color:#fff; } +#kopf #navigation { background:url(../img/navigation_bg.gif) left top no-repeat; } +#unten { background:url(../img/seitenabschluss.gif) 0 45px no-repeat; } +/* } */ + +/* { Allgemeine Typographie */ +h3 img { margin:-2em 0 0 0; } +h4 {font-weight:bold;} +select, textarea, input.text { border:1px solid #c8d200; background:#eee; } +select:focus, textarea:focus, input.text:focus { background:#fff; } +b { font-weight:bold; } + +input.text, textarea, select { width:260px; } + +form { margin:0 0 0 0; padding:0; } +form p { margin:0 0 0 0px; } +form input.knopf { margin-top:10px; } +form label { display:block; padding: 0 0 10px 0; } +form textarea { height:162px; } +form select.dropdown { width:260px; } + +.description h3 { + color:#c8d200; +} +/* } */ + +/* { Einzelregeln */ +#content div { float:left; margin:27px 0 0 -9px; } + +#content span.separator { color:#c8d200; } +#content .page_navigator { + clear:left; + position:relative; + top:-21px; + text-align:right; +} + +#content #inhalt { margin-left:41px; width:468px; } +#content #inhalt h2 { font-size:20px; color:#c8d200; padding-bottom:5px; } +#content #inhalt h3 { font-size:12px; padding-bottom:3px; font-weight:bold; } +#inhalt h5 { font-weight:bold; margin-bottom:18px; background:url(../img/punkte.gif) 0% 100% repeat-x; } +#inhalt h5 span.separator { font-weight:lighter; } +#inhalt h6 { font-size:11px; font-weight:bold; margin-bottom:27px; } +#content #inhalt p { padding:0 0 6px 0; } + +#content #news_spalte {background:url(../img/newsbox_bg.gif) 0 0 repeat; width:290px; margin:-5px 0 0 36px;} +#content #news_spalte p { float:none; padding:0 18px 0 18px;} +#content #news_spalte_bgtop {background:url(../img/newsbox_oben.gif) 0 0 no-repeat; float:right; width:290px; height:21px; margin:-18px -18px -3px 0; font-size:15px; padding:9px 0 6px 18px; font-weight:bold;} +#content #news_spalte_bgbottom {background:url(../img/newsbox_unten.gif) 0 0 no-repeat; float:right; width:290px; height:25px; margin:-9px 0 0 0;} +#content #news_spalte .link {background:url(../img/newsbox_link.gif) 0 0 no-repeat; width:244px; height:20px; margin:5px 0 9px 18px; padding:0 0 0 24px; } +#content #news_spalte h4 {margin:2px 0 0 18px; font-size:12px; font-weight:bold; } +/* +#content #info_spalte, #content #news_spalte { margin:37px 0 0 9px; } +#content #info_spalte h3, #content #news_spalte h3 { font-size:11px; background:url(../img/info_spalte.gif) 0px 1px no-repeat; width:192px; height:18px; padding:0 0 1px 9px; color:#fff; margin-bottom:18px; } +#content #info_spalte p { text-align:right; margin-bottom:9px; } + +#content #news_spalte p { text-align:left; margin:0 0 9px 10px; } +#content #news_spalte h4 { margin:18px 0 3px 10px; background:url(../img/punkte.gif) 0% 100% repeat-x; } +#content #news_spalte { width:192px; } +*/ + +.referenz_bild { + margin-top:-9px; +} +/* } */ diff --git a/public/css/screen_ie.css b/public/css/screen_ie.css new file mode 100644 index 0000000..7a727e3 --- /dev/null +++ b/public/css/screen_ie.css @@ -0,0 +1,37 @@ +table, tr, td, th { font-family:Verdana, 'Lucida Grande', Geneva, Lucida, Arial, Helvetica, sans-serif; font-size:11px; line-height:18px; color:#000; } + +/* Allgemeines Layout */ +body { text-align:center; } +#wrapper { text-align:left; height:1%; } +#content { height:1%; } +#haftungsausschluss {border:1px solid #FFF; } + +/* Einzelregeln */ +h4 { font-size:11px } + +#kundennavi a, +#subnavigation a {padding-left:21px; background:url(../img/icon_pfeil_off.gif) 0 1px no-repeat; } + + +#kundennavi a:visited, +#subnavigation a:visited {color:#808080;} + +#kundennavi a:focus, +#kundennavi a:hover, +#kundennavi a:active, +#subnavigation a:focus, +#subnavigation a:hover, +#subnavigation a:active {background:url(../img/icon_pfeil_on.gif) 0 1px no-repeat; color:#A0DA44; } + +#subnavigation a.aktiv {padding:0 0; } + +/* Kundennavi */ +body.contact #kundennavi a.contact, +body.start #kundennavi a.start, +body.sitemap #kundennavi a.sitemap { font-weight:bold; color:#A0DA44; background:url(../img/icon_pfeil_on.gif) 0 1px no-repeat; } + + +#content #news_spalte {background:url(../img/newsbox_bg.gif) 0 0 repeat; width:290px; margin:-5px 0 0 36px;} +#content #news_spalte p { float:none; padding:0 18px 0 18px;} +#content #news_spalte_bgtop {background:url(../img/newsbox_oben.gif) 0 0 no-repeat; width:290px; height:21px; margin:18px 0 -3px 36px; font-size:15px; padding:9px 0 10px 18px;} +#content #news_spalte_bgbottom {background:url(../img/newsbox_unten.gif) 0 0 no-repeat; float:right; width:290px; height:21px; margin:-9px 0 0 0; } \ No newline at end of file diff --git a/public/img/favicon.ico b/public/img/favicon.ico new file mode 100644 index 0000000..734b1d0 Binary files /dev/null and b/public/img/favicon.ico differ diff --git a/public/img/icon_pfeil_off.gif b/public/img/icon_pfeil_off.gif new file mode 100755 index 0000000..f1291f6 Binary files /dev/null and b/public/img/icon_pfeil_off.gif differ diff --git a/public/img/icon_pfeil_on.gif b/public/img/icon_pfeil_on.gif new file mode 100755 index 0000000..d16dcf9 Binary files /dev/null and b/public/img/icon_pfeil_on.gif differ diff --git a/public/img/kopf_start.jpg b/public/img/kopf_start.jpg new file mode 100755 index 0000000..44dee31 Binary files /dev/null and b/public/img/kopf_start.jpg differ diff --git a/public/img/lightbox/blank.gif b/public/img/lightbox/blank.gif new file mode 100644 index 0000000..1d11fa9 Binary files /dev/null and b/public/img/lightbox/blank.gif differ diff --git a/public/img/lightbox/close.gif b/public/img/lightbox/close.gif new file mode 100644 index 0000000..ca517b6 Binary files /dev/null and b/public/img/lightbox/close.gif differ diff --git a/public/img/lightbox/closelabel.gif b/public/img/lightbox/closelabel.gif new file mode 100644 index 0000000..4c50402 Binary files /dev/null and b/public/img/lightbox/closelabel.gif differ diff --git a/public/img/lightbox/loading.gif b/public/img/lightbox/loading.gif new file mode 100644 index 0000000..f864d5f Binary files /dev/null and b/public/img/lightbox/loading.gif differ diff --git a/public/img/lightbox/next.gif b/public/img/lightbox/next.gif new file mode 100644 index 0000000..1fe6ca1 Binary files /dev/null and b/public/img/lightbox/next.gif differ diff --git a/public/img/lightbox/nextlabel.gif b/public/img/lightbox/nextlabel.gif new file mode 100644 index 0000000..4ef202d Binary files /dev/null and b/public/img/lightbox/nextlabel.gif differ diff --git a/public/img/lightbox/prev.gif b/public/img/lightbox/prev.gif new file mode 100644 index 0000000..aefa804 Binary files /dev/null and b/public/img/lightbox/prev.gif differ diff --git a/public/img/lightbox/prevlabel.gif b/public/img/lightbox/prevlabel.gif new file mode 100644 index 0000000..112164f Binary files /dev/null and b/public/img/lightbox/prevlabel.gif differ diff --git a/public/img/logo.gif b/public/img/logo.gif new file mode 100755 index 0000000..8127c4f Binary files /dev/null and b/public/img/logo.gif differ diff --git a/public/img/logo/sideshow/logo_corpuscare.png b/public/img/logo/sideshow/logo_corpuscare.png new file mode 100755 index 0000000..15781dc Binary files /dev/null and b/public/img/logo/sideshow/logo_corpuscare.png differ diff --git a/public/img/logo/sideshow/logo_dao.png b/public/img/logo/sideshow/logo_dao.png new file mode 100755 index 0000000..266b1a7 Binary files /dev/null and b/public/img/logo/sideshow/logo_dao.png differ diff --git a/public/img/logo/sideshow/logo_dao_keyvisual.png b/public/img/logo/sideshow/logo_dao_keyvisual.png new file mode 100755 index 0000000..fc5252f Binary files /dev/null and b/public/img/logo/sideshow/logo_dao_keyvisual.png differ diff --git a/public/img/logo/sideshow/logo_myhotelvideo.png b/public/img/logo/sideshow/logo_myhotelvideo.png new file mode 100755 index 0000000..9693f2f Binary files /dev/null and b/public/img/logo/sideshow/logo_myhotelvideo.png differ diff --git a/public/img/logo/sideshow/logo_nanologika.png b/public/img/logo/sideshow/logo_nanologika.png new file mode 100755 index 0000000..d7e97fd Binary files /dev/null and b/public/img/logo/sideshow/logo_nanologika.png differ diff --git a/public/img/logo/sideshow/logo_nobilis.png b/public/img/logo/sideshow/logo_nobilis.png new file mode 100755 index 0000000..b8d6bd4 Binary files /dev/null and b/public/img/logo/sideshow/logo_nobilis.png differ diff --git a/public/img/logo/sideshow/logo_poker.png b/public/img/logo/sideshow/logo_poker.png new file mode 100755 index 0000000..052aa3f Binary files /dev/null and b/public/img/logo/sideshow/logo_poker.png differ diff --git a/public/img/logo/sideshow/logo_poker_claim.png b/public/img/logo/sideshow/logo_poker_claim.png new file mode 100755 index 0000000..759dc48 Binary files /dev/null and b/public/img/logo/sideshow/logo_poker_claim.png differ diff --git a/public/img/logo/sideshow/logo_rampenlicht.png b/public/img/logo/sideshow/logo_rampenlicht.png new file mode 100755 index 0000000..3992f96 Binary files /dev/null and b/public/img/logo/sideshow/logo_rampenlicht.png differ diff --git a/public/img/logo/sideshow/logo_travelclips.png b/public/img/logo/sideshow/logo_travelclips.png new file mode 100755 index 0000000..4495f27 Binary files /dev/null and b/public/img/logo/sideshow/logo_travelclips.png differ diff --git a/public/img/logo/teaserbilder/excerpt_corpuscare.gif b/public/img/logo/teaserbilder/excerpt_corpuscare.gif new file mode 100755 index 0000000..0ef5f46 Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_corpuscare.gif differ diff --git a/public/img/logo/teaserbilder/excerpt_dao.gif b/public/img/logo/teaserbilder/excerpt_dao.gif new file mode 100755 index 0000000..0e0ee76 Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_dao.gif differ diff --git a/public/img/logo/teaserbilder/excerpt_myhotelvideo.gif b/public/img/logo/teaserbilder/excerpt_myhotelvideo.gif new file mode 100755 index 0000000..0115b8d Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_myhotelvideo.gif differ diff --git a/public/img/logo/teaserbilder/excerpt_nanologika.gif b/public/img/logo/teaserbilder/excerpt_nanologika.gif new file mode 100755 index 0000000..c6c4671 Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_nanologika.gif differ diff --git a/public/img/logo/teaserbilder/excerpt_nobilis.gif b/public/img/logo/teaserbilder/excerpt_nobilis.gif new file mode 100755 index 0000000..5d71947 Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_nobilis.gif differ diff --git a/public/img/logo/teaserbilder/excerpt_poker.gif b/public/img/logo/teaserbilder/excerpt_poker.gif new file mode 100755 index 0000000..ea8eb9f Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_poker.gif differ diff --git a/public/img/logo/teaserbilder/excerpt_rampenlicht.gif b/public/img/logo/teaserbilder/excerpt_rampenlicht.gif new file mode 100755 index 0000000..b6423e1 Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_rampenlicht.gif differ diff --git a/public/img/logo/teaserbilder/excerpt_travelclips.gif b/public/img/logo/teaserbilder/excerpt_travelclips.gif new file mode 100755 index 0000000..138d7e3 Binary files /dev/null and b/public/img/logo/teaserbilder/excerpt_travelclips.gif differ diff --git a/public/img/navigation_bg.gif b/public/img/navigation_bg.gif new file mode 100755 index 0000000..3b5e4e5 Binary files /dev/null and b/public/img/navigation_bg.gif differ diff --git a/public/img/print/sideshow/print_corpuscare.png b/public/img/print/sideshow/print_corpuscare.png new file mode 100755 index 0000000..2c5fd30 Binary files /dev/null and b/public/img/print/sideshow/print_corpuscare.png differ diff --git a/public/img/print/sideshow/print_dao.png b/public/img/print/sideshow/print_dao.png new file mode 100755 index 0000000..0643bc1 Binary files /dev/null and b/public/img/print/sideshow/print_dao.png differ diff --git a/public/img/print/sideshow/print_dao_plakat.png b/public/img/print/sideshow/print_dao_plakat.png new file mode 100755 index 0000000..84e3fc5 Binary files /dev/null and b/public/img/print/sideshow/print_dao_plakat.png differ diff --git a/public/img/print/sideshow/print_giata_berlin.png b/public/img/print/sideshow/print_giata_berlin.png new file mode 100755 index 0000000..3cbac80 Binary files /dev/null and b/public/img/print/sideshow/print_giata_berlin.png differ diff --git a/public/img/print/sideshow/print_giata_fuerte.png b/public/img/print/sideshow/print_giata_fuerte.png new file mode 100755 index 0000000..e09e53c Binary files /dev/null and b/public/img/print/sideshow/print_giata_fuerte.png differ diff --git a/public/img/print/sideshow/print_nanologika.png b/public/img/print/sideshow/print_nanologika.png new file mode 100755 index 0000000..85fb9bd Binary files /dev/null and b/public/img/print/sideshow/print_nanologika.png differ diff --git a/public/img/print/sideshow/print_nobilis.png b/public/img/print/sideshow/print_nobilis.png new file mode 100755 index 0000000..d0cba16 Binary files /dev/null and b/public/img/print/sideshow/print_nobilis.png differ diff --git a/public/img/print/sideshow/print_poker.png b/public/img/print/sideshow/print_poker.png new file mode 100755 index 0000000..a076c35 Binary files /dev/null and b/public/img/print/sideshow/print_poker.png differ diff --git a/public/img/print/sideshow/print_rampenlicht.png b/public/img/print/sideshow/print_rampenlicht.png new file mode 100755 index 0000000..3d0574f Binary files /dev/null and b/public/img/print/sideshow/print_rampenlicht.png differ diff --git a/public/img/print/teaserbilder/excerpt_corpuscare.gif b/public/img/print/teaserbilder/excerpt_corpuscare.gif new file mode 100755 index 0000000..0ef5f46 Binary files /dev/null and b/public/img/print/teaserbilder/excerpt_corpuscare.gif differ diff --git a/public/img/print/teaserbilder/excerpt_dao.gif b/public/img/print/teaserbilder/excerpt_dao.gif new file mode 100755 index 0000000..0e0ee76 Binary files /dev/null and b/public/img/print/teaserbilder/excerpt_dao.gif differ diff --git a/public/img/print/teaserbilder/excerpt_giata.gif b/public/img/print/teaserbilder/excerpt_giata.gif new file mode 100755 index 0000000..c997958 Binary files /dev/null and b/public/img/print/teaserbilder/excerpt_giata.gif differ diff --git a/public/img/print/teaserbilder/excerpt_nanologika.gif b/public/img/print/teaserbilder/excerpt_nanologika.gif new file mode 100755 index 0000000..c6c4671 Binary files /dev/null and b/public/img/print/teaserbilder/excerpt_nanologika.gif differ diff --git a/public/img/print/teaserbilder/excerpt_nobilis.gif b/public/img/print/teaserbilder/excerpt_nobilis.gif new file mode 100755 index 0000000..5d71947 Binary files /dev/null and b/public/img/print/teaserbilder/excerpt_nobilis.gif differ diff --git a/public/img/print/teaserbilder/excerpt_poker.gif b/public/img/print/teaserbilder/excerpt_poker.gif new file mode 100755 index 0000000..ea8eb9f Binary files /dev/null and b/public/img/print/teaserbilder/excerpt_poker.gif differ diff --git a/public/img/print/teaserbilder/excerpt_rampenlicht.gif b/public/img/print/teaserbilder/excerpt_rampenlicht.gif new file mode 100755 index 0000000..b6423e1 Binary files /dev/null and b/public/img/print/teaserbilder/excerpt_rampenlicht.gif differ diff --git a/public/img/seitenabschluss.gif b/public/img/seitenabschluss.gif new file mode 100644 index 0000000..ee4b4fe Binary files /dev/null and b/public/img/seitenabschluss.gif differ diff --git a/public/img/web/sideshow/landingpage_03.jpg b/public/img/web/sideshow/landingpage_03.jpg new file mode 100755 index 0000000..de34cd8 Binary files /dev/null and b/public/img/web/sideshow/landingpage_03.jpg differ diff --git a/public/img/web/teaserbilder/excerpt_bildung.gif b/public/img/web/teaserbilder/excerpt_bildung.gif new file mode 100755 index 0000000..e9d80e4 Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_bildung.gif differ diff --git a/public/img/web/teaserbilder/excerpt_bonhoeffer.gif b/public/img/web/teaserbilder/excerpt_bonhoeffer.gif new file mode 100644 index 0000000..e9a2abb Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_bonhoeffer.gif differ diff --git a/public/img/web/teaserbilder/excerpt_cme-springer.gif b/public/img/web/teaserbilder/excerpt_cme-springer.gif new file mode 100644 index 0000000..2939d36 Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_cme-springer.gif differ diff --git a/public/img/web/teaserbilder/excerpt_ddb.gif b/public/img/web/teaserbilder/excerpt_ddb.gif new file mode 100644 index 0000000..e2a0348 Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_ddb.gif differ diff --git a/public/img/web/teaserbilder/excerpt_efors.gif b/public/img/web/teaserbilder/excerpt_efors.gif new file mode 100755 index 0000000..174ced7 Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_efors.gif differ diff --git a/public/img/web/teaserbilder/excerpt_jamba.gif b/public/img/web/teaserbilder/excerpt_jamba.gif new file mode 100755 index 0000000..492da4c Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_jamba.gif differ diff --git a/public/img/web/teaserbilder/excerpt_jobcenter-medizin.gif b/public/img/web/teaserbilder/excerpt_jobcenter-medizin.gif new file mode 100644 index 0000000..c12e4c3 Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_jobcenter-medizin.gif differ diff --git a/public/img/web/teaserbilder/excerpt_knb.gif b/public/img/web/teaserbilder/excerpt_knb.gif new file mode 100644 index 0000000..3d75eaa Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_knb.gif differ diff --git a/public/img/web/teaserbilder/excerpt_nuggad.gif b/public/img/web/teaserbilder/excerpt_nuggad.gif new file mode 100755 index 0000000..4547bbb Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_nuggad.gif differ diff --git a/public/img/web/teaserbilder/excerpt_poker.gif b/public/img/web/teaserbilder/excerpt_poker.gif new file mode 100755 index 0000000..b189a64 Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_poker.gif differ diff --git a/public/img/web/teaserbilder/excerpt_viveo.gif b/public/img/web/teaserbilder/excerpt_viveo.gif new file mode 100755 index 0000000..bc39bee Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_viveo.gif differ diff --git a/public/img/web/teaserbilder/excerpt_walomat.gif b/public/img/web/teaserbilder/excerpt_walomat.gif new file mode 100755 index 0000000..38021e9 Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_walomat.gif differ diff --git a/public/img/web/teaserbilder/excerpt_weigend.gif b/public/img/web/teaserbilder/excerpt_weigend.gif new file mode 100755 index 0000000..976bf3a Binary files /dev/null and b/public/img/web/teaserbilder/excerpt_weigend.gif differ diff --git a/public/js/basescript.js b/public/js/basescript.js new file mode 100644 index 0000000..65e5a96 --- /dev/null +++ b/public/js/basescript.js @@ -0,0 +1,162 @@ +// '); + }, + load: function() { + if((typeof Prototype=='undefined') || + parseFloat(Prototype.Version.split(".")[0] + "." + + Prototype.Version.split(".")[1]) < 1.4) + throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0"); + + $A(document.getElementsByTagName("script")).findAll( function(s) { + return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) + }).each( function(s) { + var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,''); + var includes = s.src.match(/\?.*load=([a-z,]*)/); + (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each( + function(include) { Scriptaculous.require(path+include+'.js') }); + }); + } +} + +Scriptaculous.load(); \ No newline at end of file diff --git a/public/js/moo.fx.js b/public/js/moo.fx.js new file mode 100644 index 0000000..59c98d9 --- /dev/null +++ b/public/js/moo.fx.js @@ -0,0 +1,134 @@ +// '); + }, + load: function() { + if((typeof Prototype=='undefined') || + (typeof Element == 'undefined') || + (typeof Element.Methods=='undefined') || + parseFloat(Prototype.Version.split(".")[0] + "." + + Prototype.Version.split(".")[1]) < 1.5) + throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0"); + + $A(document.getElementsByTagName("script")).findAll( function(s) { + return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/)) + }).each( function(s) { + var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,''); + var includes = s.src.match(/\?.*load=([a-z,]*)/); + (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each( + function(include) { Scriptaculous.require(path+include+'.js') }); + }); + } +} + +Scriptaculous.load(); \ No newline at end of file diff --git a/public/js/scriptaculous/slider.js b/public/js/scriptaculous/slider.js new file mode 100644 index 0000000..c0f1fc0 --- /dev/null +++ b/public/js/scriptaculous/slider.js @@ -0,0 +1,283 @@ +// Copyright (c) 2005 Marty Haught, Thomas Fuchs +// +// See http://script.aculo.us for more info +// +// 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. + +if(!Control) var Control = {}; +Control.Slider = Class.create(); + +// options: +// axis: 'vertical', or 'horizontal' (default) +// +// callbacks: +// onChange(value) +// onSlide(value) +Control.Slider.prototype = { + initialize: function(handle, track, options) { + var slider = this; + + if(handle instanceof Array) { + this.handles = handle.collect( function(e) { return $(e) }); + } else { + this.handles = [$(handle)]; + } + + this.track = $(track); + this.options = options || {}; + + this.axis = this.options.axis || 'horizontal'; + this.increment = this.options.increment || 1; + this.step = parseInt(this.options.step || '1'); + this.range = this.options.range || $R(0,1); + + this.value = 0; // assure backwards compat + this.values = this.handles.map( function() { return 0 }); + this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false; + this.options.startSpan = $(this.options.startSpan || null); + this.options.endSpan = $(this.options.endSpan || null); + + this.restricted = this.options.restricted || false; + + this.maximum = this.options.maximum || this.range.end; + this.minimum = this.options.minimum || this.range.start; + + // Will be used to align the handle onto the track, if necessary + this.alignX = parseInt(this.options.alignX || '0'); + this.alignY = parseInt(this.options.alignY || '0'); + + this.trackLength = this.maximumOffset() - this.minimumOffset(); + this.handleLength = this.isVertical() ? this.handles[0].offsetHeight : this.handles[0].offsetWidth; + + this.active = false; + this.dragging = false; + this.disabled = false; + + if(this.options.disabled) this.setDisabled(); + + // Allowed values array + this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false; + if(this.allowedValues) { + this.minimum = this.allowedValues.min(); + this.maximum = this.allowedValues.max(); + } + + this.eventMouseDown = this.startDrag.bindAsEventListener(this); + this.eventMouseUp = this.endDrag.bindAsEventListener(this); + this.eventMouseMove = this.update.bindAsEventListener(this); + + // Initialize handles in reverse (make sure first handle is active) + this.handles.each( function(h,i) { + i = slider.handles.length-1-i; + slider.setValue(parseFloat( + (slider.options.sliderValue instanceof Array ? + slider.options.sliderValue[i] : slider.options.sliderValue) || + slider.range.start), i); + Element.makePositioned(h); // fix IE + Event.observe(h, "mousedown", slider.eventMouseDown); + }); + + Event.observe(this.track, "mousedown", this.eventMouseDown); + Event.observe(document, "mouseup", this.eventMouseUp); + Event.observe(document, "mousemove", this.eventMouseMove); + + this.initialized = true; + }, + dispose: function() { + var slider = this; + Event.stopObserving(this.track, "mousedown", this.eventMouseDown); + Event.stopObserving(document, "mouseup", this.eventMouseUp); + Event.stopObserving(document, "mousemove", this.eventMouseMove); + this.handles.each( function(h) { + Event.stopObserving(h, "mousedown", slider.eventMouseDown); + }); + }, + setDisabled: function(){ + this.disabled = true; + }, + setEnabled: function(){ + this.disabled = false; + }, + getNearestValue: function(value){ + if(this.allowedValues){ + if(value >= this.allowedValues.max()) return(this.allowedValues.max()); + if(value <= this.allowedValues.min()) return(this.allowedValues.min()); + + var offset = Math.abs(this.allowedValues[0] - value); + var newValue = this.allowedValues[0]; + this.allowedValues.each( function(v) { + var currentOffset = Math.abs(v - value); + if(currentOffset <= offset){ + newValue = v; + offset = currentOffset; + } + }); + return newValue; + } + if(value > this.range.end) return this.range.end; + if(value < this.range.start) return this.range.start; + return value; + }, + setValue: function(sliderValue, handleIdx){ + if(!this.active) { + this.activeHandle = this.handles[handleIdx]; + this.activeHandleIdx = handleIdx; + this.updateStyles(); + } + handleIdx = handleIdx || this.activeHandleIdx || 0; + if(this.initialized && this.restricted) { + if((handleIdx>0) && (sliderValuethis.values[handleIdx+1])) + sliderValue = this.values[handleIdx+1]; + } + sliderValue = this.getNearestValue(sliderValue); + this.values[handleIdx] = sliderValue; + this.value = this.values[0]; // assure backwards compat + + this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = + this.translateToPx(sliderValue); + + this.drawSpans(); + if(!this.dragging || !this.event) this.updateFinished(); + }, + setValueBy: function(delta, handleIdx) { + this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, + handleIdx || this.activeHandleIdx || 0); + }, + translateToPx: function(value) { + return Math.round( + ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * + (value - this.range.start)) + "px"; + }, + translateToValue: function(offset) { + return ((offset/(this.trackLength-this.handleLength) * + (this.range.end-this.range.start)) + this.range.start); + }, + getRange: function(range) { + var v = this.values.sortBy(Prototype.K); + range = range || 0; + return $R(v[range],v[range+1]); + }, + minimumOffset: function(){ + return(this.isVertical() ? this.alignY : this.alignX); + }, + maximumOffset: function(){ + return(this.isVertical() ? + this.track.offsetHeight - this.alignY : this.track.offsetWidth - this.alignX); + }, + isVertical: function(){ + return (this.axis == 'vertical'); + }, + drawSpans: function() { + var slider = this; + if(this.spans) + $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) }); + if(this.options.startSpan) + this.setSpan(this.options.startSpan, + $R(0, this.values.length>1 ? this.getRange(0).min() : this.value )); + if(this.options.endSpan) + this.setSpan(this.options.endSpan, + $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum)); + }, + setSpan: function(span, range) { + if(this.isVertical()) { + span.style.top = this.translateToPx(range.start); + span.style.height = this.translateToPx(range.end - range.start + this.range.start); + } else { + span.style.left = this.translateToPx(range.start); + span.style.width = this.translateToPx(range.end - range.start + this.range.start); + } + }, + updateStyles: function() { + this.handles.each( function(h){ Element.removeClassName(h, 'selected') }); + Element.addClassName(this.activeHandle, 'selected'); + }, + startDrag: function(event) { + if(Event.isLeftClick(event)) { + if(!this.disabled){ + this.active = true; + + var handle = Event.element(event); + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + if(handle==this.track) { + var offsets = Position.cumulativeOffset(this.track); + this.event = event; + this.setValue(this.translateToValue( + (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2) + )); + var offsets = Position.cumulativeOffset(this.activeHandle); + this.offsetX = (pointer[0] - offsets[0]); + this.offsetY = (pointer[1] - offsets[1]); + } else { + // find the handle (prevents issues with Safari) + while((this.handles.indexOf(handle) == -1) && handle.parentNode) + handle = handle.parentNode; + + this.activeHandle = handle; + this.activeHandleIdx = this.handles.indexOf(this.activeHandle); + this.updateStyles(); + + var offsets = Position.cumulativeOffset(this.activeHandle); + this.offsetX = (pointer[0] - offsets[0]); + this.offsetY = (pointer[1] - offsets[1]); + } + } + Event.stop(event); + } + }, + update: function(event) { + if(this.active) { + if(!this.dragging) this.dragging = true; + this.draw(event); + // fix AppleWebKit rendering + if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); + Event.stop(event); + } + }, + draw: function(event) { + var pointer = [Event.pointerX(event), Event.pointerY(event)]; + var offsets = Position.cumulativeOffset(this.track); + pointer[0] -= this.offsetX + offsets[0]; + pointer[1] -= this.offsetY + offsets[1]; + this.event = event; + this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] )); + if(this.initialized && this.options.onSlide) + this.options.onSlide(this.values.length>1 ? this.values : this.value, this); + }, + endDrag: function(event) { + if(this.active && this.dragging) { + this.finishDrag(event, true); + Event.stop(event); + } + this.active = false; + this.dragging = false; + }, + finishDrag: function(event, success) { + this.active = false; + this.dragging = false; + this.updateFinished(); + }, + updateFinished: function() { + if(this.initialized && this.options.onChange) + this.options.onChange(this.values.length>1 ? this.values : this.value, this); + this.event = null; + } +} \ No newline at end of file diff --git a/public/js/sortable.js b/public/js/sortable.js new file mode 100644 index 0000000..759c725 --- /dev/null +++ b/public/js/sortable.js @@ -0,0 +1,43 @@ +//