0251 / 590 837 15
info@a-coding-project.de
;

Seitentypen Teil 2 (CMS)

Im selbst erstelltem CMS geht es heute immer noch um die Seitentypen. Eins darf ich vorher versprechen: Das Seite Bearbeiten bekommt heute endlich ein vernünftiges Layout!

Als erstes benötigen wir eine neue Tabelle! Wir müssen nämlich unsere Editor-Klassen vernünftig benennen, damit diese auch aufgelistet werden können:

CREATE TABLE `cms_pagetypes` (
`id` INT( 10 ) NOT NULL AUTO_INCREMENT ,
`class` VARCHAR( 50 ) NOT NULL ,
`name` VARCHAR( 50 ) NOT NULL ,
PRIMARY KEY ( `id` ) ) TYPE = MYISAM ;

Nun müssen wir dort den WYSIWYG Editor eintragen:

INSERT INTO `cms_pagetypes` VALUES (1, 'wysiwyg', 'Textseite');

Das ganze muss natürlich wieder im /installer/installer.php hinzugefügt werden:

private function createTables(){
      mysql_query("CREATE TABLE `".$this->params[3]['praefix']."activated_plugins` (
  `path` varchar(100) NOT NULL,
  PRIMARY KEY  (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."custom_css` (
  `id` varchar(100) NOT NULL,
  `stylePath` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."dashboards` (
  `id` int(10) NOT NULL,
  `col` int(1) NOT NULL,
  `row` int(2) NOT NULL,
  `path` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`,`col`,`row`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."events` (
  `event` varchar(50) NOT NULL,
  `file` varchar(50) NOT NULL,
  PRIMARY KEY  (`event`,`file`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."images` (
  `path` varchar(255) NOT NULL,
  `name` varchar(75) NOT NULL,
  `description` varchar(255) NOT NULL,
  PRIMARY KEY  (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."menu` (
  `id` int(2) NOT NULL,
  `menuID` int(3) NOT NULL,
  `title` varchar(100) NOT NULL,
  `href` varchar(255) NOT NULL,
  `type` int(1) NOT NULL,
  PRIMARY KEY  (`id`,`menuID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."menu_names` (
  `id` int(4) NOT NULL auto_increment,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 AUTO_INCREMENT=17 ;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."meta_global` (
  `name` varchar(100) NOT NULL,
  `content` varchar(100) NOT NULL,
  PRIMARY KEY  (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."meta_local` (
  `name` varchar(100) NOT NULL,
  `page` int(11) NOT NULL,
  `content` varchar(100) NOT NULL,
  PRIMARY KEY  (`name`,`page`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."pages` (
  `id` int(8) NOT NULL auto_increment,
  `alias` varchar(255) NOT NULL,
  `title` varchar(255) NOT NULL,
  `owner` int(11) NOT NULL default '-1',
  `menu` int(11) NOT NULL default '-1',
  `editor` varchar(50) NOT NULL default 'WYSIWYG',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=35 DEFAULT CHARSET=utf8 AUTO_INCREMENT=35 ;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."ssettings` (
  `role` int(10) NOT NULL default '3',
  `area` varchar(20) NOT NULL,
  `areaType` varchar(20) NOT NULL,
  `property` varchar(255) NOT NULL,
  `value` varchar(255) NOT NULL,
  `activated` int(1) NOT NULL default '1',
  `description` varchar(75) NOT NULL,
  `type` varchar(50) NOT NULL,
  PRIMARY KEY  (`role`,`area`,`areaType`,`property`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."skins` (
  `id` int(3) NOT NULL auto_increment,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."user` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `password` varchar(50) NOT NULL,
  `role` int(10) NOT NULL,
  PRIMARY KEY  (`id`,`name`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."widgets` (
  `path` varchar(255) NOT NULL,
  `name` varchar(50) NOT NULL,
  `class` varchar(50) NOT NULL,
  PRIMARY KEY  (`path`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."roles` (
  `id` int(10) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;");
mysql_query("CREATE TABLE `".$this->params[3]['praefix']."pagetypes` (
  `id` INT( 10 ) NOT NULL AUTO_INCREMENT ,
  `class` VARCHAR( 50 ) NOT NULL ,
  `name` VARCHAR( 50 ) NOT NULL ,
  PRIMARY KEY ( `id` ) ) TYPE = MYISAM ;");
}
    
    private function insertRows(){
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu_names` VALUES (1, '{admin}');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (1, 1, 'Dashboard', '/admin/',1;");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (2, 1, 'Seiten', '/admin/index.php?page=sites',1);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (3, 1, 'Menüs', '/admin/index.php?page=menues',1);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (4, 1, 'Dateien', '/admin/index.php?page=files',1);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (5, 1, 'Plugins', '/admin/index.php?page=plugins',1);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (7, 1, 'Einstellungen', '/admin/index.php?page=settings',1);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (8, 1, 'Benutzer', '/admin/index.php?page=user',1);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."menu` VALUES (9, 1, 'Logout', '/admin/index.php?page=logout',1);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."user` VALUES (1, '".$this->params[4]['user']."', '".md5($this->params[4]['password'])."',2);");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('global', 'global', 'title', '".$this->params[4]['name']."', 1, 'Titel des CMS','textbox');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('global', 'global', 'selectedskin', '1', 1, 'Aktueller Skin','skinselector');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('global', 'global', 'selectedmobileskin', '1', 1, 'Mobiler Skin','mobileskinselector');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('default', 'skins', 'skinbgcolor', 'dedede', 1, 'Hintergrundfarbe','colorpicker');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('default', 'skins', 'skinforecolor', '525252', 1, 'Schriftfarbe','colorpicker');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('default', 'skins', 'skinhighlight1', 'ff0000', 1, 'Highlight Farbe 1','colorpicker');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('default', 'skins', 'skinhighlight2', 'b3fa00', 1, 'Highlight Farbe 2','colorpicker');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."settings` VALUES ('global', 'global', 'host', 'http://".$_SERVER['HTTP_HOST']."', 1, 'URL der Startseite','textbox');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."skins` VALUES (1, 'default');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."skins` VALUES (2, 'mobile');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."roles` VALUES (1, 'Gast');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."roles` VALUES (2, 'Administator');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."roles` VALUES (3, 'Alle');");
      mysql_query("INSERT INTO `".$this->params[3]['praefix']."pagetypes` VALUES (1, 'wysiwyg', 'Textseite');");
    }

Für die Auflistung der Typen gibt es in der Klasse /system/classes/page.php nun die Funktion getPageTypes:

  function getPagesTypes(){
    return $GLOBALS['db']->ReadRows("SELECT * FROM {'dbprefix'}pagetypes");
  }

Diese wird sofort in der Datei /admin/includes/site-new.php verwendet:

<h1>Seite erstellen</h1>
<?PHP
  if(!$_POST['alias']){
?>
  <form action="/admin/index.php?page=site-new&dir=<?PHP echo $_GET['dir']; ?>" method="post">
    <table>
      <tr>
        <td>Typ:</td>
        <td>
          <select name="type">
            <?PHP
              $types = Page::getPagesTypes();
              if($types){
                foreach($types as $type){
                  echo "<option value='".$type->class."'>".$type->name."</option>";
                }
              }
              ?>
          </select>
        </td>
      </tr>
      <tr>
        <td>Alias:</td>  
        <td><input name="alias" /></td>
      </tr>
      <tr>
        <td></td>
        <td><input type="submit" value="Erstellen" /></td>
      </tr>
    </table>
  </form>
<?PHP
  }
  else{
   if($_GET['dir']){
     $dir = $db->EscapeString($_GET['dir'])."/";
   }
   else{
     $dir = "";
   }
   $id = Page::create("../",$dir.$db->EscapeString($_POST['alias']));
   if($id){
  ?>
    <p>Die Seite wurde erfolgreich erstellt.</p>
    <form action="/admin/index.php" method="GET">
      <input type="hidden" name="page" value="site-edit" />
      <input type="hidden" name="site" value="<?PHP echo $_POST['alias']; ?>" />
      <input type="submit" value="Seite Bearbeiten" />
    </form>
  <?PHP
    }
    else{
   ?>
      <p>Die Seite konnte leider nicht erstellt werden.</p>
   <?PHP
    }
  }
?>

Weiter gehts mit der Klasse /system/classes/editor.php. Diese bekommt die Funktion save:

<?PHP
  abstract class Editor{

    public $page    = null;
    public $content = null;   
    abstract function display();
    abstract function displayEditable();
    abstract function save($newPage,$oldPage);
    
  }
?>

In der Klasse WYSIWYG wird nun auch der WYSIWYG-Editor eingebaut. Außerdem kommen Seitenspezifische funktionen in die Datei (system/classes/wysiwyg.php). Diesmal leider ohne Syntax.Highlighting:

<?PHP class WYSIWYG extends Editor{ public function display(){ include(filterfilename("content/articles/".$this->page->alias)); } public function displayEditable(){ if($this->content == null){ $this->content = $this->readContent("../"); } ?> <script type="text/javascript" src="/system/WYSIWYG/tiny_mce.js"></script> <script type="text/javascript"> tinyMCE.init({ // General options language : "de", mode : "textareas", theme : "advanced", plugins : "safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,imagemanager,filemanager", // Theme options theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect", theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,code,|,forecolor,backcolor", theme_advanced_buttons3 : "tablecontrols,|,visualaid,|charmap,|,fullscreen,spellchecker,|,visualchars,template,blockquote,|,insertfile,insertimage", theme_advanced_toolbar_location : "top", theme_advanced_toolbar_align : "left", theme_advanced_statusbar_location : "bottom", theme_advanced_resizing : true, // Example content CSS (should be your site CSS) content_css : "css/example.css", // Drop lists for link/image/media/template dialogs template_external_list_url : "template_list.js", external_link_list_url : "link_list.js", external_image_list_url : "/content/imagelist.php", media_external_list_url : "js/media_list.js", // Replace values for the template plugin template_replace_values : { username : "Some User", staffid : "991234" } }); </script> <textarea name="content" style="width:70%;height:500px;"><?PHP echo $this->content; ?></textarea> </div> <div style="clear:both;"> <input name="vorschau" type="submit" value="Vorschau" onclick="form.action='/<?PHP echo $this->page->alias; ?>.html' ; target='_blank' ; return true" /> <input name="save" type="submit" value="Ändern" onclick="form.action='<?PHP echo $_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'] ?>' ; target='_self' ; return true" /> <?PHP } public function save($newPage,$oldPage){ $this->deleteContent("../"); $this->page = $newPage; $this->writeContent("../",$_POST['content']); } private function readContent($dirpraefix){ $filename = $dirpraefix."content/articles/".$this->page->alias.".php"; $handle = @fopen ($filename, "rb"); if($handle && filesize($filename) > 0){ $contents = fread ($handle, filesize ($filename)); fclose ($handle); } else{ $contents = ""; } return $contents; } private function deleteContent($dirpraefix){ $filename = $dirpraefix."content/articles/".$this->page->alias.".php"; if(file_exists($filename)){ unlink($filename); $args['alias'] = $this->page->alias; $args['filename'] = $filename; EventManager::raiseEvent("pagecontent_deleted","../",$args); } } function writeContent($dirpraefix,$content){ $filename = $dirpraefix."content/articles/".$this->page->alias.".php"; $handle = fopen ($filename, "a"); $res = fwrite ($handle, $content); fclose ($handle); if($res){ $args['alias'] = $alias; $args['filename'] = $filename; $args['content'] = $content; EventManager::raiseEvent("pagecontent_writed","../",$args); } return $res; } } ?>

Die Funktionen wurden natürlich aus der Klasse /system/classes/page.php entfernt:

<?PHP
class Page{
  public $id      = -1;
  public $alias   = '';
  public $title   = '';
  public $ownerid = -1;
  public $owner   = false;
  public $menu    = -1;
  public $meta    = null;
  public $editor  = null;
  
  function loadProperties($alias){
    if ($alias == "") {
      $alias = "home";
    }
    $row = $GLOBALS['db']->ReadRow("SELECT id,title,owner,menu,editor FROM {'dbprefix'}pages 
                           WHERE alias = '".$alias."'");
    if($row){
      $this->id = $row->id;
      $this->title = $row->title;
      $this->ownerid = $row->owner;
      $this->menu = $row->menu;
      $this->alias = $alias;
      $this->meta  = new Meta();
      $this->meta->pageid = $this->id;
      $this->meta->load();
      $this->editor = new $row->editor();
      $this->editor->page = $this;
    }
  }

  function getContent(){
    EventManager::raiseEvent("content_top",".",$this);
    $this->editor->display();
    EventManager::raiseEvent("content_bottom",".",$this);
  }

  function getOwner(){
    if(!$this->owner){
      $alias = $GLOBALS['db']->ReadField("SELECT alias FROM {'dbprefix'}pages 
                                          WHERE id = '".$this->ownerid."'");
      if($alias){
        $this->owner = new Page();
        $this->owner->loadProperties($alias);
      }
    }
    return $this->owner;
  }

  function getBreadcrump(){
    if(!$this->owner) $this->getOwner();
    if($this->owner){
      $breadcrump = $this->owner->getBreadcrump();
    }
    $breadcrump[] = array($this->alias,$this->title);
    return $breadcrump;
  }

  function save(){
    $res = $GLOBALS['db']->Execute("UPDATE {'dbprefix'}pages SET
                                    title = '".$this->title."',
                                    alias = '".$this->alias."',
                                    menu = '".$this->menu."' 
                                    WHERE id = '".$this->id."'");
    $this->meta->save();
    if($res){
      $args['title'] = $this->title;
      $args['alias'] = $this->alias;
      $args['menu']  = $this->menu;
      $args['id']    = $this->id;
      EventManager::raiseEvent("page_saved","../",$args);
    }
    return $res;
  }

  function create($dirpraefix,$alias){
    $res = $GLOBALS['db']->Execute("INSERT INTO {'dbprefix'}pages (alias) VALUES ('".$alias."')");
    self::writeContent($dirpraefix,"",$alias);
    if($res){
      $args['id']    = $GLOBALS['db']->InsertID();
      $args['alias'] = $alias;
      EventManager::raiseEvent("page_created","../",$args);
    }
    return $GLOBALS['db']->InsertID();
  }

  function delete(){
    $res = $GLOBALS['db']->Execute("DELETE FROM {'dbprefix'}pages WHERE alias = '".$this->alias."'");
    if($res){
      $args['alias'] = $this->alias;
      EventManager::raiseEvent("page_deleted","../",$args);
    }
    return $res;
  }

  function getPagesTypes(){
    return $GLOBALS['db']->ReadRows("SELECT * FROM {'dbprefix'}pagetypes");
  }
}

?>

Jetzt kommen wir zum Highlight des Artikels. Das neue Design der Seite-Bearbeiten Ansicht. Neben dem Verbesserten Design wird nun auch der WYSIWYG-Editor benutzt /admin/incldues/siete-edit.php:

<?PHP
  $page = new Page();
  $page->loadProperties($GLOBALS['db']->EscapeString($_GET['site']));
  
  if($_POST['save']){
    $oldpage = $page;
    $page->title = $_POST['title'];
    $page->menu = $_POST['menu'];
    $page->meta->description = $_POST['meta-description'];
    $page->meta->keywords = $_POST['meta-keywords'];
    $page->meta->robots = $_POST['meta-robots'];
    $page->alias = $_POST['alias'];
    $page->save();
    $page->editor->save($page,$oldpage);
  }
  else if(isset($_POST['menu'])){
    $page->title = $_POST['title'];
    $page->alias = $_POST['alias'];
    $page->menu = $_POST['menu'];
    $page->editor->content = $_POST['content'];
  }
?>
<h1>Seite bearbeiten</h1>
<form name="form" action="/admin/index.php?page=site-edit&site=<?PHP echo $page->alias; ?>" 
      method="post">
<div style="float:right;width:20%;">
    <label for="alias">Alias:</label>
    <input name="alias" value="<?PHP echo $page->alias; ?>" /><br />
    <h2>Seitenmen&uuml;</h2>
    <select name="menu" onchange="document.form.submit();">
      <option value="0">-- Kein Men&uuml; --</option>
<?PHP
foreach(sys::getMenues() as $menue){
    echo "<option value="".$menue->id.""";
    if($_POST['menu'] == $menue->id){
        echo " selected="selected"";
    }
    else if($page->menu == $menue->id && !$_POST['menu']){
            echo " selected="selected"";
        }
    
    echo ">".$menue->name."</option>";
}
      ?>
    </select>
    <div id="menupreview">
<?PHP
if($_POST['menu']){
    Menu::display($_POST['menu'],"<ul>","</ul>","<li>","</li>","");
}
else if($page->menu > 0){
        Menu::display($page->menu,"<ul>","</ul>","<li>","</li>","");
    }
      ?>
    </div>
    <h2>Meta Daten</h2>
    <label for="meta-description">Description:</label>
    <input name="meta-description" value="<?PHP echo $page->meta->description; ?>" /><br />
    <label for="meta-keywords">Keywords:</label>
    <input name="meta-keywords" value="<?PHP echo $page->meta->keywords; ?>" /><br />
    <label for="meta-robots">Robots:</label>
    <input name="meta-robots" value="<?PHP echo $page->meta->robots; ?>" /><br />
  </div>
  <div>
    <input name="title" value="<?PHP echo $page->title; ?>" style="width:70%;height:25px;margin-bottom:5px;font-size:20px;" /><br />
    <?PHP
      $page->editor->displayEditable();
    ?>
  </div>
</form>

Mit diesen Änderungen haben wir die Seitentypen für erste fertig. Das einzige was noch fehlt, ist das Speichern des Editors. Das werden wir im nächsten Beitrag zusammen mit der Login-Seite erstellen.