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

Rollenspezifische Einstellungen Speichern Teil 2 (CMS)

Im CMS geht es heute wieder um die rollenspezifischen Einstellungen. Wir werden 2 neue Templates erstellen und die Einstellungen für die ausgewählte Rolle im Admin-Bereich anzeigen lassen.

Fangen wir als erstes mit dem auslagern der Settings-Form als Template an. Dafür gibt es die neue Datei /system/templates/form_settings.html:

<form style="float:left;width:600px;" action="{VAR:URL}" method="post">
  Rolle: {VAR:Roles}
  <fieldset style="width:500px;">
    <legend>Einstellungen &auml;ndern</legend>
    <table style="width:100%">
      {LOOP:SETTINGS}
        <tr>
          <td>
            <label for="{VAR:PROPERTY}">
              {VAR:DESCRIPTION}
            </label>
          </td>
          <td>
            {VAR:CONTROL}
          </td>
        </tr>
      {/LOOP:SETTINGS}
    </table>
    <br />
    <input type="submit" name="save" value="Speichern" />
  </fieldset>
</form>

Dieses Template wird nun in der /system/classes/settingsform.php eingebaut:

<?PHP
  class SettingsForm{
    public $area     = "global";
    public $areaType = "global";
    public $role     = null;
    public $url      = "";
    
    public function display(){
      if($_POST['save']){
        foreach($_POST as $property=>$value){
          if($property != "save" && $property != "roles"){
            setSetting($this->area,$this->areaType,$property,$value,$currentRole);
          }
        }
      }
      $template = new Template();
      $template->load("../system/templates/form_settings.html");
        
      $roleselector = "<select name="roles" onchange="document.location.href='".$this->url."&role=' + this.options[this.selectedIndex].value;">";
        
      $roles = $GLOBALS['db']->ReadRows("SELECT * FROM {'dbprefix'}roles ORDER BY name");
      if($roles){
        foreach($roles as $role){
          if($this->role == $role->id){
            $roleselector .= "<option value="".$role->id."" selected="selected">".$role->name."</option>";
          }
          else{
            $roleselector .= "<option value="".$role->id."">".$role->name."</option>";
          }
        }
      }
        
      $roleselector .= "</select>";
      $template->assign_var("ROLES",$roleselector);
      $template->assign_var("URL",$this->url);

      $sql = "SELECT * FROM {'dbprefix'}settings WHERE area = '".$this->area."' AND areaType = '".$this->areaType."' AND activated = 1";
      if($this->role){
          $sql .= " AND role = '".$this->role."'";
      }
      $rows = $GLOBALS['db']->ReadRows($sql);
      if($rows){
        foreach($rows as $row){
          $index = $template->add_loop_item("SETTINGS");
          $template->assign_loop_var("SETTINGS", $index, "PROPERTY", $row->property);
          $template->assign_loop_var("SETTINGS", $index, "DESCRIPTION",$row->description);
          $control        = new $row->type;
          $control->name  = $row->property;
          $control->value = $row->value;
          $template->assign_loop_var("SETTINGS", $index, "CONTROL",$control->getCode());
        }
      }
      $template->output();
    }
  }
?>

Die neuen Eigenschaften role und url müssen nun in der /admin/includes/settings.php gesetzt werden:

<h1>Einstellungen</h1>
<?PHP
  $settings = new SettingsForm();
  $settings->role = 3;
  if($_GET['role']) $settings->role = $_GET['role'];
  $settings->url  = "/admin/index.php?page=settings";
  $settings->display();
?>
<div style="margin-left:500px;">
<h2>Skins</h2>
<?PHP
  $skins = $GLOBALS['db']->ReadRows("SELECT * FROM {'dbprefix'}skins WHERE LOWER(name) IN (SELECT DISTINCT name FROM {'dbprefix'}settings WHERE areaType = 'skins' AND area = {'dbprefix'}skins.name)");
  if($skins){
    foreach($skins as $skin){
      echo "<a href="/admin/index.php?page=skin-settings&skin=".urlencode($skin->name)."">".$skin->name."</a><br />";
    }
  }
?>
<h2>Plugins</h2>
<?PHP
  $plugins = new PluginList();
  $plugins->loadAll();
  foreach($plugins->plugins as $plugin){
    if($plugin->configurationFile != ''){
      ?>
      <a href="/admin/index.php?page=plugin-settings&plugin=<?PHP echo $plugin->path; ?>"><?PHP echo $plugin->name; ?></a><br />
      <?PHP
    }
  }
?>
</div>

Da wir in den Templates den Quellcode der Controls brauchen und diese nicht sofort anzeigen müssen wir alle Controls überarbeiten. Zu aller erst gibt es die neue Funktion getCode() in der abstrakten Klasse control. Die Funktion display wird nun nicht mehr abstrakt. Sie ruft die neue Funktion einfach auf. /system/classes/control.php:

<?PHP
  abstract class Control{
    public $name  = "";
    public $value = "";

    public function display(){
        echo $this->getCode();
    }
    
    public abstract function getCode();
  }
?>

Die nächsten paar Änderungen erkläre ich jetzt nicht ausführlich, da sich hier eigentlich nur das echo mit einem return ausgetauscht und die Funktion umbenannt wurde. /system/classes/menueselector.php:

<?PHP
  class menueselector extends Control{
    public $style = '';
    
    public function getCode(){
      $res = "<select name="".$this->name."" style="".$this->style."">";
      foreach(sys::getMenues() as $menue){
        if($menue->id == $this->value){
          $res .= "<option value="".$menue->id."" selected="1">".$menue->name."</option>";
        }
        else{
          $res .= "<option value="".$menue->id."">".$menue->name."</option>";
        }
      }
      $res .= "</select>";
       return $res;
    }

  }
?>

/system/classes/textbox.php:

<?PHP
  class textbox extends Control{
    
    public function getCode(){
      return "<input name="".htmlentities($this->name)."" value="".htmlentities($this->value)."" />";
    }

  }
?>

Bei den Skinselectors wird es schon etwas schwieriger. Da dort zu viel Html, PHP & JavaScript gemixt wurde habe ich mich dafür entschlossen auch hier ein Template zu erstellen (/system/templates/control_skinselector.html)

<input type="hidden" name="{VAR:NAME}" value="{VAR:VALUE}" />
<img id="{VAR:SELECTORNAME}btnLeft" OnClick="document.getElementsByName('{VAR:NAME}')[0].value--;
                                     document.getElementById('{VAR:SELECTORNAME}skinpreview').src='/system/skins/' + {VAR:SELECTORNAME}skins[document.getElementsByName('{VAR:NAME}')[0].value-1]['name'] + '/screenshot.jpg';
                                     document.getElementById('{VAR:SELECTORNAME}btnRight').style.visibility='visible';
                                     if(1 == document.getElementsByName('{VAR:NAME}')[0].value){
                                         document.getElementById('{VAR:SELECTORNAME}btnLeft').style.visibility='hidden'
                                     };"
                             src="/system/images/btnLeft.gif" />
<img id="{VAR:SELECTORNAME}skinpreview" style="border:1px solid #aaa" src="/system/skins/{VAR:CURRENTSKINNAME}/screenshot.jpg" />
<img id="{VAR:SELECTORNAME}btnRight" OnClick="document.getElementsByName('{VAR:NAME}')[0].value++;
                                      document.getElementById('{VAR:SELECTORNAME}skinpreview').src='/system/skins/' + {VAR:SELECTORNAME}skins[document.getElementsByName('{VAR:NAME}')[0].value-1]['name'] + '/screenshot.jpg';
                                      if({VAR:SELECTORNAME}skins.length == document.getElementsByName('{VAR:NAME}')[0].value){
                                          document.getElementById('{VAR:SELECTORNAME}btnRight').style.visibility='hidden';
                                      }
                                      document.getElementById('{VAR:SELECTORNAME}btnLeft').style.visibility='visible';" 
                             src="/system/images/btnRight.gif" />
<script language="JavaScript">
  var {VAR:SELECTORNAME}skins = new Array();
  {LOOP:SKINS}
    {VAR:SELECTORNAME}skins[{VAR:INDEX}] = new Object();
    {VAR:SELECTORNAME}skins[{VAR:INDEX}]["id"] = "{VAR:SKINID}";
    {VAR:SELECTORNAME}skins[{VAR:INDEX}]["name"] = "{VAR:SKINNAME}";
  {/LOOP:SKINS}
  if({VAR:SELECTORNAME}skins.length == document.getElementsByName("{VAR:NAME}")[0].value){
    document.getElementById('{VAR:SELECTORNAME}btnRight').style.visibility='hidden';
  }
  if(1 == document.getElementsByName('{VAR:NAME}')[0].value){
    document.getElementById('{VAR:SELECTORNAME}btnLeft').style.visibility='hidden';
  }
</script>

In der KLasse /system/classes/skinselector.php wird nun auf dieses neue Template zugegriffen:

<?PHP
  class skinselector extends Control{
    public $type = "";
    
     public function getCode(){
      $template = new Template();
      $template->load("../system/templates/control_skinselector.html");
      $template->assign_var("NAME",$this->name);
      $template->assign_var("SELECTORNAME",$this->type);
      $template->assign_var("VALUE",$this->value);
      $template->assign_var("CURRENTSKINNAME",SkinController::getSkinName($this->value));
      $i = 0;
      foreach(SkinController::getInstalledSkins() as $skin){
        $index = $template->add_loop_item("SKINS");
        $template->assign_loop_var("SKINS", $index, "SELECTORNAME",$this->type);
        $template->assign_loop_var("SKINS", $index, "INDEX", $i);
        $template->assign_loop_var("SKINS", $index, "SKINID", $skin->id);
        $template->assign_loop_var("SKINS", $index, "SKINNAME", $skin->name);
        $i++;
      }
      return $template->getCode();
    }

  }
?>

Für diese Änderung müssen die Klassen Template und SkinController erweitert werden. Fangen wir an mit der Klasse /system/classes/template.php. Bei ihr muss man wie bei den Controls den Quellcode über die Methode getCode() bekommen:

public function getCode(){
  foreach($this->loops as $key => $array){
    $loop_template = implode("n", $array);
    $this->template = str_ireplace('<!--LOOP('.strtoupper($key).')-->', $loop_template, $this->template);
  }
  return $this->template;
}

public function output(){
  echo $this->getCode();
}

Die Klasse /system/classes/skincontroller.php wird mit der Funktion getSkinName bestückt:

function getSkinName($id){
  $id = $GLOBALS['db']->EscapeString($id);
  return $GLOBALS['db']->ReadField("SELECT name FROM {'dbprefix'}skins WHERE id = '".$id."'");
}

Fehlt nur noch die Klasse /system/classes/mobileskinselector.php. Diese wird jetzt statt von control von skinselector geerbt. So sparen wir uns doppelten Quellcode:

<?PHP
  class mobileskinselector extends skinselector{

    public function __construct(){
      $this->type = "mobile";
    }

  }
?>

Das wars auch schon für heute. Im nächsten Teil werden wir dann wahrscheinlich wirklich ans speichern gehen 😉