*/ if (!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../../../') . '/'); if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); if(!defined('HTMLOK_WIKI_PATH'))define ('HTMLOK_WIKI_PATH', DOKU_INC . 'data/pages/'); if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/'); define('AUTH_USERFILE', DOKU_CONF . 'users.auth.php'); require_once(DOKU_PLUGIN . 'admin.php'); /** * All DokuWiki plugins to extend the admin function * need to inherit from this class */ class admin_plugin_htmlOKay extends DokuWiki_Admin_Plugin { var $output; var $ajax_script = 'directory_scan-3.php'; var $path = HTMLOK_WIKI_PATH; var $wiki_home = HTMLOK_WIKI_PATH; var $directories = array(); var $global_conf; var $plugin_name; var $current_namespace; var $users; var $groups = array(); var $scrollbars = false; var $namespace_descriptor = '_ROOT_'; var $saved_inf; // either data read from access file at startup or data saved from $_POST var $error_msg; var $user_entries = 0; var $show_debug = false; function __construct() { global $conf; $this->plugin_name ='htmlOKay'; $this->current_namespace = rtrim($this->path, '/'); $this->_loadUserData(); $script = DOKU_PLUGIN . $this->plugin_name . '/' . $this->ajax_script; $document_root = $_SERVER['DOCUMENT_ROOT']; $url = preg_replace('/' . preg_quote($document_root, '/') . '/', "", $script); $this->ajax_script = $url; $this->global_conf = $conf; $this->init(); $this->traverseDirTree($this->path, 'outputpath', 'outputpath'); } /** * return some info */ function getInfo() { return array('author' => 'Myron Turner', 'email' => 'Myron_Turner@shaw.ca', 'date' => '2015-09-03', 'name' => 'HTML Access Manager', 'desc' => 'sets permissions for html write/edit access', 'url' => 'http://www.mturner.org/htmlaccess/', ); } /** * return sort order for position in admin menu */ function getMenuSort() { return 929; } function getMenuText($language) { return 'HTML Access Manager'; } /** * handle user request */ function handle() { if (!isset($_REQUEST['abs_path'])) // first time through { $this->namespace_file = preg_replace('/\:/', '#', $this->namespace_descriptor); $data_file = DOKU_PLUGIN . $this->plugin_name . '/conf/access/' . $this->namespace_file; $this->saved_inf = io_readFile($data_file, false); // 'false' returns uncleaned string for unserialize if(isset($this->saved_inf)) { $this->saved_inf = unserialize($this->saved_inf); } return; } // Saving access files begins here $this->filespecs = $_POST['filespecs']; $this->request = $_REQUEST; $this->output = $_POST; $this->current_namespace = $_POST['abs_path']; $this->namespace_descriptor = $this->directories[$this->current_namespace]['namespace']; $this->namespace_file = preg_replace('/\:/', '#', $this->namespace_descriptor); if (!isset($_POST['group']) && !isset($_POST['user'])) { $this->error_msg = "HTML Permissions for " . $this->namespace_file ." have been removed."; } elseif ($this->filespecs[0] == 'none') { $this->error_msg = "Incomplete data: No files selected"; return; } $data_file = DOKU_PLUGIN . $this->plugin_name . '/conf/access/' . $this->namespace_file; $this->namespace_file = $data_file; $inf = $this->get_output_array(); if(!$inf) $inf = array(); $this->saved_inf = $inf; $inf = serialize($inf); io_saveFile($data_file, $inf, false); } function get_output_array() { $new_inf = array(); $keys = array_keys($this->output); if (!in_array('group', $keys) && !in_array('user', $keys)) return false; $levels = array('none' => 0, 'strict' => 1, 'medium' => 2, 'lax' => 3, 'su' => 4); $display = 4; foreach($this->output as $item => $val) { if ($item != 'filespecs' && $item != 'group' && $item != 'user' && $item != 'abs_path') continue; if ($item == 'group' || $item == 'user') // get lowest HTML permissions for display { foreach($val as $name => $level) // display is in effect when HTML viewed by non-editor { if ($levels[$level] < $display) { $display = $levels[$level]; } } } $new_inf[$item] = $val; } $levels = array_keys($levels); $new_inf['display'] = $levels[$display]; $new_inf['namespace'] = $this->namespace_file; return $new_inf; } function init() { $this->wiki_home = rtrim($this->wiki_home, '/'); $this->directories[$this->wiki_home]['name'] = '_ROOT_'; $this->directories[$this->wiki_home]['namespace'] = '_ROOT_'; $this->wiki_home = ltrim($this->wiki_home, '/'); $this->wiki_home = preg_quote($this->wiki_home, '/'); } /** * Load all user data * * loads the user file into a datastructure * * adapted from DokuWiki plain.class.php */ function _loadUserData() { $this->users = array(); if (!@file_exists(AUTH_USERFILE)) return; $lines = file(AUTH_USERFILE); foreach($lines as $line) { $line = preg_replace('/#.*$/', '', $line); //ignore comments $line = trim($line); if (empty($line)) continue; $row = explode(":", $line, 5); $groups = explode(",", $row[4]); $this->users[$row[0]]['name'] = urldecode($row[2]); $this->users[$row[0]]['mail'] = $row[3]; $this->users[$row[0]]['grps'] = $groups; foreach($groups as $grp) { $this->groups[$grp][] = $row[0]; } } } /** * Constructs namespace from directory path * Called by output_path when constructing $directories array */ function get_namespace($path) { $namespace_string = trim($path, '/'); $namespace_string = preg_replace('/^' . $this->wiki_home . '/', "", $namespace_string); $namespace_string = preg_replace('%/%', ':', $namespace_string); return ltrim($namespace_string, ':'); } /** * Adapted from http://www.safalra.com/programming/php/directry-tree-traversal.php */ function traverseDirTree($base, $fileFunc, $dirFunc = null, $afterDirFunc = null) { if(!is_readable ($base)) { msg("$base is not readable (htmlOkay, line 225)",2); return; } $subdirectories = opendir($base); while (($subdirectory = readdir($subdirectories)) !== false) { $path = $base . $subdirectory; if (is_file($path)) { if ($fileFunc !== null) $this->$fileFunc($path); } else { if ($dirFunc !== null) $this->$dirFunc($path); if (($subdirectory != '.') && ($subdirectory != '..')) { $this->traverseDirTree($path . '/', $fileFunc, $dirFunc, $afterDirFunc); } if ($afterDirFunc !== null) $this->$afterDirFunc($path); } } closedir($subdirectories); } function outputPath($path) { $name = basename($path); if ($name == '.' || $name == '..') return; if (is_dir($path)) { $this->directories[$path] = array(); $this->directories[$path]['name'] = $name; $this->directories[$path]['namespace'] = $this->get_namespace($path); $this->directories[$path]['files'] = array(); } elseif (is_file($path)) { $dir = dirname($path); $this->directories[$dir]['files'][] = $name; } } function get_directory_options() { $options = array(); foreach($this->directories as $dir => $info) { if (!isset($info['namespace'])) continue; $selected = ""; if ($dir == $this->current_namespace) { $selected = 'SELECTED'; } $options[] = "' ; } return $options; } function get_group_options() { $options = array(); $groups = $this->groups; foreach($groups as $group => $val) { list($checked_strict, $checked_medium, $checked_lax, $su) = $this->get_checked($group, $this->saved_inf['group']); $options[] = "" . "" . "" . "R" . "$group"; } return $options; } function get_file_options($dir) { $options = array(); $default_selected = true; $options[] = '' ; $options[] = '' ; $files = $this->directories[$dir]['files']; foreach($files as $file) { $selected = ""; if (isset($this->saved_inf['filespecs'])) { if (in_array ($file, $this->saved_inf['filespecs'])) { $default_selected = false; $selected = "selected"; } } $options[] = "' ; } if ($default_selected) { $options[0] = '' ; } return $options; } // find previously checked radio buttons for form's user and group elements function get_checked($name, $info_array) { $checked_strict = ""; $checked_medium = ""; $checked_lax = ""; $checked_su = ""; if (isset($info_array)) { if (array_key_exists($name, $info_array)) { switch ($info_array[$name]) { case 'strict': $checked_strict = 'checked'; break; case 'medium': $checked_medium = 'checked'; break; case 'lax': $checked_lax = 'checked'; case 'su': $checked_su = 'checked'; break; } } } return array($checked_strict, $checked_medium, $checked_lax, $checked_su); } function get_user_options() { $options = array(); foreach($this->users as $user => $user_array) { $groups = implode(',', $user_array['grps']); list($checked_strict, $checked_medium, $checked_lax, $checked_su) = $this->get_checked($user, $this->saved_inf['user']); $options[] = '' . '' . '' . '' . '' . '' . '' . '' . "R" . "\n$user" . $user_array['name'] . '' . '' . $user_array['mail'] . '' . $groups . ''; } /* causes javascript to call scrollbars_htmlOKay() on loading IE doesn't require scrollbars because overflow doesn't overwrite elements beneath the users table but instead pushes them down the page */ if (count($options) > 4 && !preg_match('/MSIE\s+\d+/', $_SERVER['HTTP_USER_AGENT'])) { $this->scrollbars = true; $this->user_entries = count($options); } return $options; } /** * Output Javascript for html file */ function print_scripts($url) { $path = HTMLOK_WIKI_PATH; $url = '/' . ltrim($url, '/'); echo << SCRIPTS; } /** * output appropriate html */ function html() { global $ID; $this->print_scripts($this->ajax_script); echo "
\n"; $this->debug(false,false); ptln('

Embedded HTML Access Manager

'); if ($this->error_msg) { print "

$this->error_msg

"; } ptln('
'); ptln('
'); echo $this->locale_xhtml('selection'); ptln("\n
\n"); /* Start Form */ ptln("\n" . '
'); ptln('' . "\n" . ''); /* Namespace Table */ ptln(''); $this->write_SELECT('Namespace', 'abs_path', 'get_directory_options', ""); $this->write_SELECT('Files', 'filespecs[]', 'get_file_options', rtrim($this->current_namespace, '/'), 'multiple size="3" ', 'results' ); echo "
\n"; /* Buttons */ ptln('
'); ptln(''); ptln(''); ptln('     '); ptln('
'); ptln('
'); // Start outer table /* Groups Table */ ptln('
'); ptln(''); ptln(''); $options = $this->get_group_options(); foreach($options as $option) { ptln("$option"); } ptln('
PolicyGroups
HMLReset
'); // End Groups table /* Users Table */ ptln('
' . '' . ' '); ptln(''); $options = $this->get_user_options(); foreach($options as $option) { ptln('' . $option); } ptln('
PolicyUserReal NameEmailGroups
HMLUReset
'); // End users table /* Close Table, close Form */ ptln("\n
\n"); ptln("

\n"); echo "
\n"; // close htmlOK_div if ($this->scrollbars) { ptln(''); } } /** * $th: heading * $name: name of the Select * $options_func: the name of the options function from which to get optons and values * $param: optional parameter to be passed in to options_func * $select_type: optional multiple and size * $id: for file options that are being replaced vi the AJAX call */ function write_SELECT($th, $name, $options_func, $param = "", $select_type = "", $id = "") { $button_fields = array('abs_path' => '', 'filespecs[]' => ' Use Ctrl or Options key to
multiple select from: 
  ' . $this->directories[$this->current_namespace]['namespace'] . '', 'groupspecs[]' => "Button" ); if ($id) { $id = ' id="' . $id . '" '; } ptln('' . "\n$th\n" . ''); ptln(' '); ptln($button_fields[$name] . ''); } function debug($users = false, $groups = false) { if(!$this->show_debug) return; global $INFO; global $conf; echo '
';
        echo "

\$INFO

"; print_r($INFO); echo "

\$conf

"; print_r($conf); echo "

Saved inf:

"; print_r($this->saved_inf); echo "

request:

"; print_r($this->request); echo "File: $this->namespace_file \n"; if($groups) { echo "

Group(s)

"; print_r ($this->groups); } if($users) { echo "

User(s):

"; print_r ($this->users); } echo "Output:
";print_r($this->output); echo "Script: " .$this->ajax_script . " <--> Path: $this->ajax_path_temp\n"; echo "
"; } } ?>