PHP Classes

File: class.config_webedit.php

Recommend this page to a friend!
  Classes of Keyvan Minoukadeh   Config Manager   class.config_webedit.php   Download  
File: class.config_webedit.php
Role: ???
Content type: text/plain
Description: Class - config web editor
Class: Config Manager
Sorry, no longer supported
Author: By
Last change:
Date: 21 years ago
Size: 13,417 bytes
 

Contents

Class file image Download
<?php /* vim: set ai tabstop=4: */ // $Date: 2002/04/09 01:29:38 $ // $Revision: 1.4 $ // +----------------------------------------------------------------------+ // | CONFIG MANAGER 0.1.2 - 09-Apr-2002 | // +----------------------------------------------------------------------+ // | Author: Keyvan Minoukadeh - keyvan@k1m.com - http://www.k1m.com | // +----------------------------------------------------------------------+ // | PHP class for managing plain text config files. | // +----------------------------------------------------------------------+ // | This program is free software; you can redistribute it and/or | // | modify it under the terms of the GNU General Public License | // | as published by the Free Software Foundation; either version 2 | // | of the License, or (at your option) any later version. | // | | // | This program is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU General Public License for more details. | // +----------------------------------------------------------------------+ if (defined('CONFIGMAN_DIR')) { require_once(CONFIGMAN_DIR.'class.config_base.php'); } /** * Config manager web editor class * * Use this class to modify your config files through a web form * This is an extension to the base config class. * * @author Keyvan Minoukadeh <keyvan@k1m.com> * @version 0.1.2 */ class config_webedit extends config_base { /** * show section names */ var $show_sections = true; /** * show string quotes */ var $show_quotes = true; /** * show static existing value */ var $show_existing = true; /** * show comments */ var $show_comments = true; /** * show types */ var $show_types = true; /** * allow type change ($this->show_types must be true) */ var $allow_type_change = false; // If you've made a stylesheet for your page, // enter name of each CSS class to use for each // element. /** * CSS class names * * main table class - <table> * type drop down class - <select> * type text - <div> * var name class - <div> * value input class - <input type='text'...> * error text class - <span> * existing static value - <span> * comment class - <div> * section name class - <td> * submit button class - <input type='submit'...> * reset button class - <input type='reset'...> */ var $css = array('main' => 'configmanMain', 'type' => 'configmanType', 'type_text' => 'configmanTypeText', 'var' => 'configmanVar', 'value' => 'configmanValue', 'error' => 'configmanError', 'existing' => 'configmanExisting', 'comment' => 'configmanComment', 'section' => 'configmanSection', 'submit' => 'configmanSubmit', 'reset' => 'configmanReset'); /** * Comment line separator */ var $comment_separator = "<br />"; /** * Confirmation text to appear when the 'Revert back' button is clicked * * Note: this will be entered in a javascript function surrounded by single quotes, * so make sure you escape properly */ var $reset_confirm_text = "This will revert all values back, any changes you\\'ve made will be lost. Are you sure you want to continue?"; /** * row color 1 */ var $row_color_1 = "#DAEBFC"; /** * row color 2 */ var $row_color_2 = "#C1DDF9"; ///////////// // methods ///////////// /** * Constructor * * @param string $config config file to use */ function config_webedit($config) { // run base constructor $this->config_base($config); } /** * Build form * * @param string $section Section to display (empty string: all sections) * @param string $post_action URL to post to (<form action=''...>) default: current page * @return string string containing the form */ function build_form($section='', $post_action=null) { $func_name = 'build_form'; clearstatcache(); if (is_null($post_action)) { if (function_exists('version_compare') && version_compare(phpversion(), '4.1.0', '>=')) { $post_action = $_SERVER['PHP_SELF']; } else { $post_action = $GLOBALS['PHP_SELF']; } } if ($this->is_file_valid()) { $config_size = filesize($this->config); $config_mtime = filemtime($this->config); $config = file($this->config); } else { $this->_error("Config file does not exist, is unreadable or above max size limit"); return false; } if (!empty($section)) { if ($this->debug) $this->_debug("$func_name: Building web form for config section '$section'"); $this_section = false; } else { if ($this->debug) $this->_debug("$func_name: Building web form for all config sections"); $this_section = true; } $diff_color = true; $form = array(); $cur_comment = array(); $form[] = "<form method=\"post\" name=\"CONFIGMAN_FORM\" action=\"{$post_action}\">"; $form[] = "<input type=\"hidden\" name=\"CONFIGMAN_INFO[action]\" value=\"modify\" />"; $form[] = "<input type=\"hidden\" name=\"CONFIGMAN_INFO[size]\" value=\"{$config_size}\" />"; $form[] = "<input type=\"hidden\" name=\"CONFIGMAN_INFO[mtime]\" value=\"{$config_mtime}\" />"; $form[] = "<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"{$this->css['main']}\">"; foreach ($config as $num => $line) { $line = trim($line); // match comment if ($this_section && $this->show_comments && preg_match('!^'.preg_quote($this->comment).'(.*)$!', $line, $match)) { if (trim($match[1]) != '') { $cur_comment[] = trim($match[1]); } continue; } // match var if ($this_section && preg_match('!^'.$this->regex_type.'?('.$this->regex_var.')(\.'.$this->regex_assoc.')?\s*'. preg_quote($this->separator).'\s*(.*)$!i', $line, $match)) { // decide which bg color to use $diff_color = ($diff_color ? false : true); if ($diff_color) { $bg_color = $this->row_color_1; } else { $bg_color = $this->row_color_2; } // add comment row if ($this->show_comments && count($cur_comment)) { $form[] = "<tr bgcolor=\"{$bg_color}\">\n\t<td><div class=\"{$this->css['comment']}\">".implode($this->comment_separator, $cur_comment)."</div></td>\n</tr>"; // reset comments captured $cur_comment = array(); } // start row $form[] = "<tr bgcolor=\"{$bg_color}\">\n\t<td>"; $form[] = "\t<table border=\"0\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\">"; $form[] = "\t<tr>"; // add var name $form[] = "\t\t<td width=\"25%\" valign=\"top\"><div class=\"{$this->css['var']}\">{$match[2]}{$match[3]}</div></td>"; // add drop down type if (!empty($match[1])) { if ($this->show_types && $this->allow_type_change) { $form[] = "\t\t<td width=\"10%\" align=\"center\" valign=\"top\"><select name=\"CONFIGMAN[{$num}][type]\" class=\"{$this->css['type']}\">"; foreach ($this->type_prefix as $prefix => $type) { if ($prefix == $match[1]) { $form[] = "\t\t\t<option value=\"{$prefix}\" selected=\"selected\">{$type}</option>"; } else { $form[] = "\t\t\t<option value=\"{$prefix}\">{$type}</option>"; } } $form[] = "\t\t</select></td>"; // add type name } elseif ($this->show_types) { $form[] = "\t\t<td width=\"10%\" align=\"center\" valign=\"top\"><div class=\"{$this->css['type_text']}\">". "<input type=\"hidden\" name=\"CONFIGMAN[{$num}][type]\" value=\"{$match[1]}\" />". $this->type_prefix[$match[1]]."</div></td>"; // empty cell } else { $form[] = "\t\t<td width=\"10%\">". "<input type=\"hidden\" name=\"CONFIGMAN[{$num}][type]\" value=\"{$match[1]}\" />". "&nbsp;</td>"; } } else { $form[] = "\t\t<td width=\"10%\">&nbsp;</td>"; } // valid quote usage? if (preg_match('!^(?'.'>(["\'])?)(.*)(?(1)\1)$!', $match[4], $value_match)) { $valid_value = true; $display_value = $value_match[2]; } else { $valid_value = false; $display_value = $match[4]; } // show quotes? if ($this->show_quotes && $valid_value) { $cur_quote = htmlspecialchars($value_match[1]); } else { $cur_quote = ''; } // show static existing values if ($this->show_existing) { $cur_existing = htmlspecialchars($match[4]); } else { $cur_existing = ''; } // add value input field $form[] = "\t\t<td width=\"65%\" valign=\"top\"><input type=\"text\" name=\"CONFIGMAN[{$num}][value]\" value=\"{$cur_quote}". htmlspecialchars($display_value)."{$cur_quote}\" class=\"{$this->css['value']}\" />&nbsp;". "<span class=\"{$this->css['existing']}\"> {$cur_existing}</span>"; if (!$valid_value) { $form[] = "\t\t<br /><span class=\"{$this->css['error']}\">Invalid value (opening AND closing quotes required)</span>"; } $form[] = "\t\t</td>"; $form[] = "\t</tr></table>\n\t</td>\n</tr>"; continue; } // match section if (preg_match('!^\[('.$this->regex_section.')\]!', $line, $match)) { $match[1] = trim($match[1]); if (empty($section) || ($match[1] === $section)) { $this_section = true; if ($this->show_sections) { $form[] = "<tr>\n\t<td>&nbsp;</td>\n</tr>"; $form[] = "<tr>\n\t<td class=\"{$this->css['section']}\">{$match[1]}</td>\n</tr>"; } } else { $this_section = false; } // reset any comments captured $cur_comment = array(); continue; } } // submit and reset buttons $form[] = "<tr>\n\t<td>&nbsp;<br />". "<input type=\"submit\" name=\"submit\" value=\"Update!\" class=\"{$this->css['submit']}\" />". " &nbsp; &nbsp; &nbsp; ". "<input type=\"reset\" name=\"reset\" value=\"Revert back\" class=\"{$this->css['reset']}\" ". "onclick=\"return confirm('{$this->reset_confirm_text}')\" />". "</td>\n</tr>"; $form[] = "</table>\n</form>"; return implode("\n", $form); } /** * Update config * * @param array $configman Result of form post ($CONFIGMAN array) * @param array $configman_info Result of form post ($CONFIGMAN_INFO array) * @return bool true on success, false otherwise */ function update($configman, $configman_info) { $func_name = 'update'; if (empty($configman_info['action']) || empty($configman_info['size']) || empty($configman_info['mtime'])) { if ($this->debug) $this->_debug("$func_name: Required info not included in array"); return false; } // get rid of magic crap $this->strip_magic_slashes($configman); $this->strip_magic_slashes($configman_info); if ($this->is_file_valid() && is_writable($this->config)) { // check action if ($configman_info['action'] !== 'modify') { if ($this->debug) $this->_debug("$func_name: Incorrect action"); return false; } // check file size if ((int)$configman_info['size'] !== filesize($this->config)) { if ($this->debug) $this->_debug("$func_name: Config file sizes do not match"); return false; } // check modification time if ((int)$configman_info['mtime'] !== filemtime($this->config)) { if ($this->debug) $this->_debug("$func_name: Config file has already been modified (modification time mismatch)"); return false; } $config = file($this->config); } else { $this->_error("Config file does not exist or is unreadable or unwritable"); return false; } $new = array(); foreach ($config as $num => $line) { $line = rtrim($line); if (!isset($configman[$num])) { $new[] = $line; continue; } if (preg_match('!^(\s*)'.$this->regex_type.'?('.$this->regex_var.')(\.'.$this->regex_assoc.')?(\s*'. preg_quote($this->separator).'\s*)(.*)$!i', $line, $match)) { // set new type if (isset($configman[$num]['type'])) { $new_type = $configman[$num]['type']; } else { $new_type = $match[2]; } // set new value $new_val = $configman[$num]['value']; $new[] = $match[1].$new_type.$match[3].$match[4].$match[5].$new_val; continue; } $new[] = $line; } $fp = @fopen($this->config, "w"); if (!$fp) { if ($this->debug) $this->_debug("$func_name: Could not create/access file"); return false; } else { // exclusive lock flock($fp, 2); $result = @fwrite($fp, implode("\n", $new)); // release lock flock($fp, 3); fclose($fp); if (!$result) { if ($this->debug) $this->_debug("$func_name: Could not write to file"); return false; } else { if ($this->debug) $this->_debug("$func_name: Config file written"); // touch file with modification time of main config file (used for comparison) touch($this->config); return true; } } // should not reach here return false; } } ?>