Code

Updated class names
authorhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 10 Mar 2010 09:33:00 +0000 (09:33 +0000)
committerhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 10 Mar 2010 09:33:00 +0000 (09:33 +0000)
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@16368 594d385d-05f5-0310-b6e9-bd551577e9d8

gosa-core/include/class_filterEditor.inc [deleted file]
gosa-core/include/class_filterEditorEntry.inc [deleted file]
gosa-core/include/class_userFilter.inc [new file with mode: 0644]
gosa-core/include/class_userFilterEditor.inc [new file with mode: 0644]

diff --git a/gosa-core/include/class_filterEditor.inc b/gosa-core/include/class_filterEditor.inc
deleted file mode 100644 (file)
index 91ae157..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-
-class userFilter extends plugin 
-{
-  protected $fitlers = array();
-  protected $availableCategories = array();
-  
-  public $objectClass = array('gosaProperties');
-  public $attributes = array('gosaUserDefinedFilter');
-  public $gosaUserDefinedFilter = array();
-  
-  /*! \brief  Initiates the filter editing dialog.
-   */ 
-  function __construct($config, $categories)
-  {
-    // Initialize this plugin with the users dn to gather user defined filters.
-    $ui = get_userinfo();
-    plugin::plugin($config, $ui->dn);
-
-    // Keep list of currently managed categories.
-    $this->availableCategories = array_unique($categories);
-    $this->availableCategories[] = 'systems';
-    $this->availableCategories[] = 'phones';
-    $this->availableCategories[] = 'printer';
-    $this->availableCategories[] = 'component';
-
-    // Load list of filters
-    if(isset($this->attrs['gosaUserDefinedFilter'])){
-      for($i=0; $i< $this->attrs['gosaUserDefinedFilter']['count']; $i++){
-        list($categories, $name, $description, $filter, $flags) = split(";", $this->attrs['gosaUserDefinedFilter'][$i]);
-   
-        // Ensure that we no empty category in our category list.
-        if(empty($categories)){
-          $categories = array();
-        }else{
-          $categories = split(',', $categories);
-        }
-
-        // Ensure that we no empty entry in out flags list.
-        if(empty($flags)){
-          $flags = array();
-        }else{
-          $flags = split(',', $flags);
-        }
-
-        // build up filter entry.
-        $tmp = array(
-            'name' => $name, 
-            'categories' => $categories,
-            'description' => base64_decode($description),
-            'filter' => base64_decode($filter),
-            'flags' => $flags);
-
-
-        $this->filters[$name] = $tmp; 
-      }
-    }
-
-    // Create the filter list
-    $this->filterWidget= new sortableListing();
-    $this->filterWidget->setDeleteable(true);
-    $this->filterWidget->setEditable(true);
-    $this->filterWidget->setWidth("100%");
-    $this->filterWidget->setHeight("270px");
-    $this->filterWidget->setColspecs(array('100px', '200px', '100px', '70px','150px'));
-    $this->filterWidget->setAcl($ui->get_permissions($ui->dn,'users/user','gosaUserDefinedFilter'));
-    $this->filterWidget->setListData($this->filters, $this->convertFilterList());
-  }
-
-
-  /*! \brief    Converts the list of filters ($this->filters) into data which is useable
-   *             for the sortableList object ($this->filterWidget).
-   *  @return   Array   An array containg data useable for sortableLists ($this->filterWidget)
-   */
-  function convertFilterList()
-  { 
-    $data = array();
-    foreach($this->filters as $name => $filter){
-      $data[$name] = array('data' =>
-          array(
-            $filter['name'],
-            $filter['description'],
-            implode(", ",$filter['categories']),
-            implode(", ",$filter['flags'])));
-    }
-    return($data); 
-  }
-
-
-  /*! \brief    Display the user-filter overview as HTML content.
-   *  @return   string    HTML-content showing the user-filter editing dialog.
-   */
-  function execute()
-  {
-    plugin::execute();
-
-    // Cancel filter modifications (edit dialog)
-    if(isset($_POST['cancelFilterSettings'])){
-      $this->dialog = NULL;
-    }
-
-    // Save modified filter entries (edit dialog)
-    if(isset($_POST['saveFilterSettings']) && $this->dialog instanceOf userFilterEditor){
-      $this->dialog->save_object();
-      $msgs = $this->dialog->check();
-      if(count($msgs)){
-        msg_dialog::displayChecks($msgs);
-      }else{
-        $orig_name = $this->dialog->getOriginalName();
-        $new_name = $this->dialog->getCurrentName();
-
-        // The object was renamed and
-        if($orig_name != $new_name && isset($this->filters[$new_name])){
-          $msgs = array(msgPool::duplicated(_("Name")));
-          msg_dialog::displayChecks($msgs);
-        }else{
-
-          // Remove old entry if filter was renamed
-          if($orig_name != "" && isset($this->filters[$orig_name])){
-            unset($this->filters[$orig_name]);
-          }
-          
-          // Now append the new filter object.
-          $this->filters[$new_name] = $this->dialog->save();
-          $this->dialog = NULL;
-          $this->filterWidget->setListData($this->filters, $this->convertFilterList());
-          $this->filterWidget->update();
-        }
-      }
-    }
-
-    // Act on edit requests 
-    $this->filterWidget->save_object();
-    $action = $this->filterWidget->getAction();
-    if($action['action'] == 'edit' && count($action['targets']) == 1){
-      $key= $this->filterWidget->getKey($action['targets'][0]);
-      if(isset($this->filters[$key])){
-        $this->dialog=new userFilterEditor($this->filters[$key], $this->availableCategories);
-      }
-    }
-
-    // Act on new requests
-    if(isset($_POST['addFilter'])){
-      $this->dialog=new userFilterEditor(array(), $this->availableCategories);
-    }
-
-    // Act on remove requests 
-    $action = $this->filterWidget->getAction();
-    if($action['action'] == 'delete' && count($action['targets']) == 1){
-      $key= $this->filterWidget->getKey($action['targets'][0]);
-      if(isset($this->filters[$key])){
-        unset($this->filters[$key]);
-        $this->filterWidget->update();
-      }
-    }
-
-    // Display edit dialog
-    if($this->dialog instanceOf userFilterEditor){
-      $this->dialog->save_object();
-      return($this->dialog->execute());
-    }
-
-    $smarty = get_smarty();
-    $smarty->assign("list", $this->filterWidget->render());
-    return($smarty->fetch(get_template_path('userFilter.tpl', FALSE)));
-  }
-
-
-  /*! \brief    Write user-filter modifications back to the ldap.  
-   */
-  function save()
-  {
-    // Build up new list of filters 
-    $attrs = array();
-    foreach($this->filters as $filter){
-      $tmp = implode(',', $filter['categories']).";";
-      $tmp.= $filter['name'].";";
-      $tmp.= base64_encode($filter['description']).";";
-      $tmp.= base64_encode($filter['filter']).";";
-      $tmp.= implode(',', $filter['flags']);
-      $attrs[] = $tmp;
-    }
-    $this->gosaUserDefinedFilter = $attrs;
-
-    plugin::save();
-
-    $ldap = $this->config->get_ldap_link();
-    $ldap->cd($this->dn);
-    $ldap->modify($this->attrs);
-    
-    new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
-
-    if (!$ldap->success()){
-      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MODIFY, get_class()));
-    }
-  }  
-
-  
-  /*! \brief    Do not save any posted values here.
-   */
-  function save_object(){}
-}
-
-// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
-?>
diff --git a/gosa-core/include/class_filterEditorEntry.inc b/gosa-core/include/class_filterEditorEntry.inc
deleted file mode 100644 (file)
index 5719106..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-
-class userFilterEditor extends plugin 
-{
-  // The original entry else array(), allows us to perform existence checks.
-  public $entry = array();
-
-  // The values
-  public $name = "";
-  public $description = "";
-  public $selectedCategories = array();
-  public $share = FALSE;
-  public $enabled = TRUE;
-  public $filter = "(objectClass=*)";
-
-  // The list of all categories mangaged by the current filter object.
-  // Used in the grop-down box.
-  public $availableCategories = array();
-  public $orig_name = "";
-
-
-  /*! \brief    Instantiate the filter editing dialog. 
-   *            Parses the filter info into editable data.
-   */
-  function __construct($entry, $categories)
-  {
-    $this->availableCategories = $categories;
-    if($entry){
-      $this->entry = $entry;
-      $this->name = $entry['name'];
-      $this->description = $entry['description'];
-      $this->filter = $entry['filter'];
-      $this->selectedCategories = $entry['categories'];
-      $this->share = in_array("share",$entry['flags']);
-      $this->enable = in_array("enable",$entry['flags']);
-    }
-    $this->orig_name = $this->name;
-  }
-
-
-  /*! \brief    Retunrs the filters original name 
-   *  @param    The original name of the filter (if none was given 
-   *             an empty string is returned)
-   */
-  function getOriginalName()
-  {
-    return($this->orig_name);
-  }
-
-
-  /*! \brief    Retunrs the filters name.
-   *  @param    The name of the filter
-   */
-  function getCurrentName()
-  {
-    return($this->name);
-  }
-
-
-  /*! \brief    Generates the <HTML> content, to edit the filter settings.
-   *  @return   String  HTML form.
-   */
-  function execute()
-  {
-    plugin::execute();
-    $smarty = get_smarty();
-    $smarty->assign('name', $this->name);
-    $smarty->assign('filter', $this->filter);
-    $smarty->assign('share', $this->share);
-    $smarty->assign('enable', $this->enabled);
-    $smarty->assign('description', $this->description);
-    $smarty->assign('selectedCategories', $this->selectedCategories);
-    $smarty->assign('availableCategories', $this->availableCategories);
-    return($smarty->fetch(get_template_path('userFilterEditor.tpl', FALSE)));
-  }
-
-
-  /*! \brief    Keep values entered in the input form of the dialog. (POST/GET)
-   */
-  function save_object()
-  {
-    if(isset($_POST['userFilterEditor'])){
-
-      // Get posted strings
-      foreach(array('name','description','filter') as $attr){
-        if(isset($_POST[$attr])){
-          $this->$attr = get_post($attr);
-        }
-      }
-
-      // Get posted flags 
-      $this->share = isset($_POST['shareFilter']);
-      $this->enable = isset($_POST['enableFilter']);
-
-      // Get additional category  
-      if(isset($_POST['addCategory'])){
-        if(isset($_POST['manualCategory']) && !empty($_POST['manualCategory'])){
-          $this->selectedCategories[] = get_post('manualCategory');
-        }elseif(isset($_POST['availableCategory']) && !empty($_POST['availableCategory'])){
-          $this->selectedCategories[] = get_post('availableCategory');
-        }
-      }
-
-      // Remove categories
-      if(isset($_POST['delCategory']) && isset($_POST['usedCategory'])){
-        foreach($_POST['usedCategory'] as $cat){
-          if(isset($this->selectedCategories[$cat])) unset($this->selectedCategories[$cat]);
-        }
-      }
-    }
-  }
-
-  
-  /*! \brief    Validate user input 
-   *  @return   Array   An Array containing potential error messages
-   */
-  function check()
-  {
-    $msgs = plugin::check();
-  
-    // Check if the name is given
-    if(empty($this->name)){
-      $msgs[] = msgPool::required(_("Name"));
-    }elseif(preg_match("/[^a-z0-9\-_ ]/i", $this->name)){
-      
-      // Check for a valid name, no special chars here - in particular no ; 
-      $msgs[] = msgPool::invalid(_("Name"), $this->name,"/[a-z0-9\-_ ]/i");
-    }  
-
-    return($msgs);
-  }
-
-
-  /*! \brief    Transforms the entered values into a filter object (array) which is useable
-   *             for the userFilter overview dialog.
-   *  @return   Returns transformed filter data.
-   */
-  function save()
-  {
-    $ret= array();
-    $ret['name'] = $this->name;
-    $ret['description'] = $this->description;
-    $ret['categories'] = $this->selectedCategories;
-    $ret['filter'] = $this->filter;
-    $ret['flags'] = array();
-    if($this->share){
-      $ret['flags'][] = "share";
-    }
-    if($this->enable){
-      $ret['flags'][] = "enable";
-    }
-    return($ret);
-  }
-}
-
-// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
-?>
diff --git a/gosa-core/include/class_userFilter.inc b/gosa-core/include/class_userFilter.inc
new file mode 100644 (file)
index 0000000..91ae157
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+
+class userFilter extends plugin 
+{
+  protected $fitlers = array();
+  protected $availableCategories = array();
+  
+  public $objectClass = array('gosaProperties');
+  public $attributes = array('gosaUserDefinedFilter');
+  public $gosaUserDefinedFilter = array();
+  
+  /*! \brief  Initiates the filter editing dialog.
+   */ 
+  function __construct($config, $categories)
+  {
+    // Initialize this plugin with the users dn to gather user defined filters.
+    $ui = get_userinfo();
+    plugin::plugin($config, $ui->dn);
+
+    // Keep list of currently managed categories.
+    $this->availableCategories = array_unique($categories);
+    $this->availableCategories[] = 'systems';
+    $this->availableCategories[] = 'phones';
+    $this->availableCategories[] = 'printer';
+    $this->availableCategories[] = 'component';
+
+    // Load list of filters
+    if(isset($this->attrs['gosaUserDefinedFilter'])){
+      for($i=0; $i< $this->attrs['gosaUserDefinedFilter']['count']; $i++){
+        list($categories, $name, $description, $filter, $flags) = split(";", $this->attrs['gosaUserDefinedFilter'][$i]);
+   
+        // Ensure that we no empty category in our category list.
+        if(empty($categories)){
+          $categories = array();
+        }else{
+          $categories = split(',', $categories);
+        }
+
+        // Ensure that we no empty entry in out flags list.
+        if(empty($flags)){
+          $flags = array();
+        }else{
+          $flags = split(',', $flags);
+        }
+
+        // build up filter entry.
+        $tmp = array(
+            'name' => $name, 
+            'categories' => $categories,
+            'description' => base64_decode($description),
+            'filter' => base64_decode($filter),
+            'flags' => $flags);
+
+
+        $this->filters[$name] = $tmp; 
+      }
+    }
+
+    // Create the filter list
+    $this->filterWidget= new sortableListing();
+    $this->filterWidget->setDeleteable(true);
+    $this->filterWidget->setEditable(true);
+    $this->filterWidget->setWidth("100%");
+    $this->filterWidget->setHeight("270px");
+    $this->filterWidget->setColspecs(array('100px', '200px', '100px', '70px','150px'));
+    $this->filterWidget->setAcl($ui->get_permissions($ui->dn,'users/user','gosaUserDefinedFilter'));
+    $this->filterWidget->setListData($this->filters, $this->convertFilterList());
+  }
+
+
+  /*! \brief    Converts the list of filters ($this->filters) into data which is useable
+   *             for the sortableList object ($this->filterWidget).
+   *  @return   Array   An array containg data useable for sortableLists ($this->filterWidget)
+   */
+  function convertFilterList()
+  { 
+    $data = array();
+    foreach($this->filters as $name => $filter){
+      $data[$name] = array('data' =>
+          array(
+            $filter['name'],
+            $filter['description'],
+            implode(", ",$filter['categories']),
+            implode(", ",$filter['flags'])));
+    }
+    return($data); 
+  }
+
+
+  /*! \brief    Display the user-filter overview as HTML content.
+   *  @return   string    HTML-content showing the user-filter editing dialog.
+   */
+  function execute()
+  {
+    plugin::execute();
+
+    // Cancel filter modifications (edit dialog)
+    if(isset($_POST['cancelFilterSettings'])){
+      $this->dialog = NULL;
+    }
+
+    // Save modified filter entries (edit dialog)
+    if(isset($_POST['saveFilterSettings']) && $this->dialog instanceOf userFilterEditor){
+      $this->dialog->save_object();
+      $msgs = $this->dialog->check();
+      if(count($msgs)){
+        msg_dialog::displayChecks($msgs);
+      }else{
+        $orig_name = $this->dialog->getOriginalName();
+        $new_name = $this->dialog->getCurrentName();
+
+        // The object was renamed and
+        if($orig_name != $new_name && isset($this->filters[$new_name])){
+          $msgs = array(msgPool::duplicated(_("Name")));
+          msg_dialog::displayChecks($msgs);
+        }else{
+
+          // Remove old entry if filter was renamed
+          if($orig_name != "" && isset($this->filters[$orig_name])){
+            unset($this->filters[$orig_name]);
+          }
+          
+          // Now append the new filter object.
+          $this->filters[$new_name] = $this->dialog->save();
+          $this->dialog = NULL;
+          $this->filterWidget->setListData($this->filters, $this->convertFilterList());
+          $this->filterWidget->update();
+        }
+      }
+    }
+
+    // Act on edit requests 
+    $this->filterWidget->save_object();
+    $action = $this->filterWidget->getAction();
+    if($action['action'] == 'edit' && count($action['targets']) == 1){
+      $key= $this->filterWidget->getKey($action['targets'][0]);
+      if(isset($this->filters[$key])){
+        $this->dialog=new userFilterEditor($this->filters[$key], $this->availableCategories);
+      }
+    }
+
+    // Act on new requests
+    if(isset($_POST['addFilter'])){
+      $this->dialog=new userFilterEditor(array(), $this->availableCategories);
+    }
+
+    // Act on remove requests 
+    $action = $this->filterWidget->getAction();
+    if($action['action'] == 'delete' && count($action['targets']) == 1){
+      $key= $this->filterWidget->getKey($action['targets'][0]);
+      if(isset($this->filters[$key])){
+        unset($this->filters[$key]);
+        $this->filterWidget->update();
+      }
+    }
+
+    // Display edit dialog
+    if($this->dialog instanceOf userFilterEditor){
+      $this->dialog->save_object();
+      return($this->dialog->execute());
+    }
+
+    $smarty = get_smarty();
+    $smarty->assign("list", $this->filterWidget->render());
+    return($smarty->fetch(get_template_path('userFilter.tpl', FALSE)));
+  }
+
+
+  /*! \brief    Write user-filter modifications back to the ldap.  
+   */
+  function save()
+  {
+    // Build up new list of filters 
+    $attrs = array();
+    foreach($this->filters as $filter){
+      $tmp = implode(',', $filter['categories']).";";
+      $tmp.= $filter['name'].";";
+      $tmp.= base64_encode($filter['description']).";";
+      $tmp.= base64_encode($filter['filter']).";";
+      $tmp.= implode(',', $filter['flags']);
+      $attrs[] = $tmp;
+    }
+    $this->gosaUserDefinedFilter = $attrs;
+
+    plugin::save();
+
+    $ldap = $this->config->get_ldap_link();
+    $ldap->cd($this->dn);
+    $ldap->modify($this->attrs);
+    
+    new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
+
+    if (!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MODIFY, get_class()));
+    }
+  }  
+
+  
+  /*! \brief    Do not save any posted values here.
+   */
+  function save_object(){}
+}
+
+// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
+?>
diff --git a/gosa-core/include/class_userFilterEditor.inc b/gosa-core/include/class_userFilterEditor.inc
new file mode 100644 (file)
index 0000000..5719106
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+
+class userFilterEditor extends plugin 
+{
+  // The original entry else array(), allows us to perform existence checks.
+  public $entry = array();
+
+  // The values
+  public $name = "";
+  public $description = "";
+  public $selectedCategories = array();
+  public $share = FALSE;
+  public $enabled = TRUE;
+  public $filter = "(objectClass=*)";
+
+  // The list of all categories mangaged by the current filter object.
+  // Used in the grop-down box.
+  public $availableCategories = array();
+  public $orig_name = "";
+
+
+  /*! \brief    Instantiate the filter editing dialog. 
+   *            Parses the filter info into editable data.
+   */
+  function __construct($entry, $categories)
+  {
+    $this->availableCategories = $categories;
+    if($entry){
+      $this->entry = $entry;
+      $this->name = $entry['name'];
+      $this->description = $entry['description'];
+      $this->filter = $entry['filter'];
+      $this->selectedCategories = $entry['categories'];
+      $this->share = in_array("share",$entry['flags']);
+      $this->enable = in_array("enable",$entry['flags']);
+    }
+    $this->orig_name = $this->name;
+  }
+
+
+  /*! \brief    Retunrs the filters original name 
+   *  @param    The original name of the filter (if none was given 
+   *             an empty string is returned)
+   */
+  function getOriginalName()
+  {
+    return($this->orig_name);
+  }
+
+
+  /*! \brief    Retunrs the filters name.
+   *  @param    The name of the filter
+   */
+  function getCurrentName()
+  {
+    return($this->name);
+  }
+
+
+  /*! \brief    Generates the <HTML> content, to edit the filter settings.
+   *  @return   String  HTML form.
+   */
+  function execute()
+  {
+    plugin::execute();
+    $smarty = get_smarty();
+    $smarty->assign('name', $this->name);
+    $smarty->assign('filter', $this->filter);
+    $smarty->assign('share', $this->share);
+    $smarty->assign('enable', $this->enabled);
+    $smarty->assign('description', $this->description);
+    $smarty->assign('selectedCategories', $this->selectedCategories);
+    $smarty->assign('availableCategories', $this->availableCategories);
+    return($smarty->fetch(get_template_path('userFilterEditor.tpl', FALSE)));
+  }
+
+
+  /*! \brief    Keep values entered in the input form of the dialog. (POST/GET)
+   */
+  function save_object()
+  {
+    if(isset($_POST['userFilterEditor'])){
+
+      // Get posted strings
+      foreach(array('name','description','filter') as $attr){
+        if(isset($_POST[$attr])){
+          $this->$attr = get_post($attr);
+        }
+      }
+
+      // Get posted flags 
+      $this->share = isset($_POST['shareFilter']);
+      $this->enable = isset($_POST['enableFilter']);
+
+      // Get additional category  
+      if(isset($_POST['addCategory'])){
+        if(isset($_POST['manualCategory']) && !empty($_POST['manualCategory'])){
+          $this->selectedCategories[] = get_post('manualCategory');
+        }elseif(isset($_POST['availableCategory']) && !empty($_POST['availableCategory'])){
+          $this->selectedCategories[] = get_post('availableCategory');
+        }
+      }
+
+      // Remove categories
+      if(isset($_POST['delCategory']) && isset($_POST['usedCategory'])){
+        foreach($_POST['usedCategory'] as $cat){
+          if(isset($this->selectedCategories[$cat])) unset($this->selectedCategories[$cat]);
+        }
+      }
+    }
+  }
+
+  
+  /*! \brief    Validate user input 
+   *  @return   Array   An Array containing potential error messages
+   */
+  function check()
+  {
+    $msgs = plugin::check();
+  
+    // Check if the name is given
+    if(empty($this->name)){
+      $msgs[] = msgPool::required(_("Name"));
+    }elseif(preg_match("/[^a-z0-9\-_ ]/i", $this->name)){
+      
+      // Check for a valid name, no special chars here - in particular no ; 
+      $msgs[] = msgPool::invalid(_("Name"), $this->name,"/[a-z0-9\-_ ]/i");
+    }  
+
+    return($msgs);
+  }
+
+
+  /*! \brief    Transforms the entered values into a filter object (array) which is useable
+   *             for the userFilter overview dialog.
+   *  @return   Returns transformed filter data.
+   */
+  function save()
+  {
+    $ret= array();
+    $ret['name'] = $this->name;
+    $ret['description'] = $this->description;
+    $ret['categories'] = $this->selectedCategories;
+    $ret['filter'] = $this->filter;
+    $ret['flags'] = array();
+    if($this->share){
+      $ret['flags'][] = "share";
+    }
+    if($this->enable){
+      $ret['flags'][] = "enable";
+    }
+    return($ret);
+  }
+}
+
+// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
+?>