Subversion Repositories oidplus

Rev

Rev 261 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. if (!defined('IN_OIDPLUS')) die();
  21.  
  22. class OIDplusPagePublicResources extends OIDplusPagePluginPublic {
  23.  
  24.         public static function getPluginInformation() {
  25.                 $out = array();
  26.                 $out['name'] = 'Resources';
  27.                 $out['author'] = 'ViaThinkSoft';
  28.                 $out['version'] = null;
  29.                 $out['descriptionHTML'] = null;
  30.                 return $out;
  31.         }
  32.  
  33.         public function priority() {
  34.                 return 500;
  35.         }
  36.  
  37.         public function action(&$handled) {
  38.                 // Nothing
  39.         }
  40.  
  41.         public function init($html=true) {
  42.                 OIDplus::config()->prepareConfigKey('resource_plugin_autoopen_level', 'Resource plugin: How many levels should be open in the treeview when OIDplus is loaded?', 1, OIDplusConfig::PROTECTION_EDITABLE, function($value) {
  43.                         if (!is_numeric($value) || ($value < 0)) {
  44.                                 throw new OIDplusException("Please enter a valid value.");
  45.                         }
  46.                 });
  47.                 OIDplus::config()->prepareConfigKey('resource_plugin_title',          'Resource plugin: Title of the resource section?', 'Documents and resources', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
  48.                         if (empty($value)) {
  49.                                 throw new OIDplusException("Please enter a title.");
  50.                         }
  51.                 });
  52.                 OIDplus::config()->prepareConfigKey('resource_plugin_path',           'Resource plugin: Path that contains the documents?', 'res/', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
  53.                         // TODO: check if path exists
  54.                 });
  55.                 OIDplus::config()->prepareConfigKey('resource_plugin_hide_empty_path','Resource plugin: Hide empty paths? 1=on, 0=off', 1, OIDplusConfig::PROTECTION_EDITABLE, function($value) {
  56.                         if (!is_numeric($value) || (($value != 0) && ($value != 1))) {
  57.                                 throw new OIDplusException("Please enter a valid value (0=off, 1=on).");
  58.                         }
  59.                 });
  60.         }
  61.  
  62.         private static function getDocumentTitle($file) {
  63.                 $cont = file_get_contents($file);
  64.                 if (preg_match('@<title>(.+)</title>@ismU', $cont, $m)) return $m[1];
  65.                 if (preg_match('@<h1>(.+)</h1>@ismU', $cont, $m)) return $m[1];
  66.                 if (preg_match('@<h2>(.+)</h2>@ismU', $cont, $m)) return $m[1];
  67.                 if (preg_match('@<h3>(.+)</h3>@ismU', $cont, $m)) return $m[1];
  68.                 if (preg_match('@<h4>(.+)</h4>@ismU', $cont, $m)) return $m[1];
  69.                 if (preg_match('@<h5>(.+)</h5>@ismU', $cont, $m)) return $m[1];
  70.                 if (preg_match('@<h6>(.+)</h6>@ismU', $cont, $m)) return $m[1];
  71.                 return pathinfo($file, PATHINFO_FILENAME); // filename without extension
  72.         }
  73.  
  74.         public function gui($id, &$out, &$handled) {
  75.                 if (explode('$',$id)[0] === 'oidplus:resources') {
  76.                         $handled = true;
  77.  
  78.                         $file = @explode('$',$id)[1];
  79.                         $auth = @explode('$',$id)[2];
  80.  
  81.                         if (!OIDplus::authUtils()::validateAuthKey("resources;$file", $auth)) {
  82.                                 $out['title'] = 'Access denied';
  83.                                 $out['icon'] = 'img/error_big.png';
  84.                                 $out['text'] = '<p>Invalid authentication token</p>';
  85.                                 return $out;
  86.                         }
  87.  
  88.                         if (strpos($file, OIDplus::config()->getValue('resource_plugin_path', 'res/')) !== 0) {
  89.                                 $out['title'] = 'Access denied';
  90.                                 $out['icon'] = 'img/error_big.png';
  91.                                 $out['text'] = '<p>Security breach A</p>';
  92.                                 return $out;
  93.                         }
  94.  
  95.                         if (strpos($file, '..') !== false) {
  96.                                 $out['title'] = 'Access denied';
  97.                                 $out['icon'] = 'img/error_big.png';
  98.                                 $out['text'] = '<p>Security breach B</p>';
  99.                                 return $out;
  100.                         }
  101.  
  102.                         $out['text'] = '';
  103.  
  104.                         if ($file != OIDplus::config()->getValue('resource_plugin_path', 'res/')) {
  105.                                 $dir = dirname($file).'/';
  106.  
  107.                                 if ($dir == OIDplus::config()->getValue('resource_plugin_path', 'res/')) {
  108.                                         if (file_exists(__DIR__.'/treeicon.png')) {
  109.                                                 $tree_icon = OIDplus::webpath(__DIR__).'treeicon.png';
  110.                                         } else {
  111.                                                 $tree_icon = null; // default icon (folder)
  112.                                         }
  113.  
  114.                                         $ic = empty($tree_icon) ? '' : '<img src="'.$tree_icon.'" alt="">';
  115.  
  116.                                         $out['text'] .= '<p><a '.OIDplus::gui()->link('oidplus:resources$'.OIDplus::config()->getValue('resource_plugin_path', 'res/').'$'.OIDplus::authUtils()::makeAuthKey("resources;".OIDplus::config()->getValue('resource_plugin_path', 'res/'))).'><img src="img/arrow_back.png" width="16"> Go back to: '.$ic.' '.htmlentities(OIDplus::config()->getValue('resource_plugin_title', 'Documents and resources')).'</a></p>';
  117.                                 } else {
  118.                                         $icon_candidate = pathinfo($dir)['dirname'].'/'.pathinfo($dir)['filename'].'_tree.png';
  119.                                         if (file_exists($icon_candidate)) {
  120.                                                 $tree_icon = $icon_candidate;
  121.                                         } else if (file_exists(__DIR__.'/treeicon_folder.png')) {
  122.                                                 $tree_icon = OIDplus::webpath(__DIR__).'treeicon_folder.png';
  123.                                         } else {
  124.                                                 $tree_icon = null; // no icon
  125.                                         }
  126.  
  127.                                         $ic = empty($tree_icon) ? '' : '<img src="'.$tree_icon.'" alt="">';
  128.  
  129.                                         $out['text'] .= '<p><a '.OIDplus::gui()->link('oidplus:resources$'.$dir.'$'.OIDplus::authUtils()::makeAuthKey("resources;$dir")).'><img src="img/arrow_back.png" width="16"> Go back to: '.$ic.' '.htmlentities(basename($dir)).'</a></p><br>';
  130.                                 }
  131.                         }
  132.  
  133.                         if (file_exists($file) && (!is_dir($file))) {
  134.                                 if (substr($file,-4,4) == '.url') {
  135.                                         $out['title'] = $this->getHyperlinkTitle($file);
  136.  
  137.                                         $icon_candidate = pathinfo($file)['dirname'].'/'.pathinfo($file)['filename'].'_big.png';
  138.                                         if (file_exists($icon_candidate)) {
  139.                                                 $out['icon'] = $icon_candidate;
  140.                                         } else if (file_exists(__DIR__.'/icon_leaf_url_big.png')) {
  141.                                                 $out['icon'] = OIDplus::webpath(__DIR__).'icon_leaf_url_big.png';
  142.                                         } else {
  143.                                                 $out['icon'] = '';
  144.                                         }
  145.  
  146.                                         // Should not happen though, due to conditionalselect
  147.                                         $out['text'] .= '<a href="'.htmlentities(self::getHyperlinkURL($file)).'" target="_blank">Open in new window</a>';
  148.                                 } else if ((substr($file,-4,4) == '.htm') || (substr($file,-5,5) == '.html')) {
  149.                                         $out['title'] = $this->getDocumentTitle($file);
  150.  
  151.                                         $icon_candidate = pathinfo($file)['dirname'].'/'.pathinfo($file)['filename'].'_big.png';
  152.                                         if (file_exists($icon_candidate)) {
  153.                                                 $out['icon'] = $icon_candidate;
  154.                                         } else if (file_exists(__DIR__.'/icon_leaf_doc_big.png')) {
  155.                                                 $out['icon'] = OIDplus::webpath(__DIR__).'icon_leaf_doc_big.png';
  156.                                         } else {
  157.                                                 $out['icon'] = '';
  158.                                         }
  159.  
  160.                                         $cont = file_get_contents($file);
  161.                                         $cont = preg_replace('@^(.+)<body[^>]*>@isU', '', $cont);
  162.                                         $cont = preg_replace('@</body>.+$@isU', '', $cont);
  163.                                         $cont = preg_replace('@<title>.+</title>@isU', '', $cont);
  164.                                         $cont = preg_replace('@<h1>.+</h1>@isU', '', $cont, 1);
  165.  
  166.                                         $out['text'] .= $cont;
  167.                                 } else {
  168.                                         $out['title'] = 'Unknown file type';
  169.                                         $out['icon'] = 'img/error_big.png';
  170.                                         $out['text'] = '<p>The system does not know how to handle this file type.</p>';
  171.                                         return $out;
  172.                                 }
  173.                         } else if (is_dir($file)) {
  174.                                 $out['title'] = ($file == OIDplus::config()->getValue('resource_plugin_path', 'res/')) ? OIDplus::config()->getValue('resource_plugin_title', 'Documents and resources') : basename($file);
  175.  
  176.                                 if ($file == OIDplus::config()->getValue('resource_plugin_path', 'res/')) {
  177.                                         $out['icon'] = file_exists(__DIR__.'/icon_big.png') ? OIDplus::webpath(__DIR__).'icon_big.png' : '';
  178.                                 } else {
  179.                                         $icon_candidate = pathinfo($file)['dirname'].'/'.pathinfo($file)['filename'].'_big.png';
  180.                                         if (file_exists($icon_candidate)) {
  181.                                                 $out['icon'] = $icon_candidate;
  182.                                         } else if (file_exists(__DIR__.'/icon_folder_big.png')) {
  183.                                                 $out['icon'] = OIDplus::webpath(__DIR__).'icon_folder_big.png';
  184.                                         } else {
  185.                                                 $out['icon'] = null; // no icon
  186.                                         }
  187.                                 }
  188.  
  189.                                 if (file_exists(__DIR__.'/treeicon.png')) {
  190.                                         $tree_icon = OIDplus::webpath(__DIR__).'treeicon.png';
  191.                                 } else {
  192.                                         $tree_icon = null; // default icon (folder)
  193.                                 }
  194.  
  195.                                 $count = 0;
  196.  
  197.                                 $dirs = glob($file.'*'.'/', GLOB_ONLYDIR);
  198.                                 natcasesort($dirs);
  199.                                 foreach ($dirs as $dir) {
  200.                                         $icon_candidate = pathinfo($dir)['dirname'].'/'.pathinfo($dir)['filename'].'_tree.png';
  201.                                         if (file_exists($icon_candidate)) {
  202.                                                 $tree_icon = $icon_candidate;
  203.                                         } else if (file_exists(__DIR__.'/treeicon_folder.png')) {
  204.                                                 $tree_icon = OIDplus::webpath(__DIR__).'treeicon_folder.png';
  205.                                         } else {
  206.                                                 $tree_icon = null; // no icon
  207.                                         }
  208.  
  209.                                         $ic = empty($tree_icon) ? '' : '<img src="'.$tree_icon.'" alt="">';
  210.  
  211.                                         $out['text'] .= '<p><a '.OIDplus::gui()->link('oidplus:resources$'.$dir.'$'.OIDplus::authUtils()::makeAuthKey("resources;$dir")).'>'.$ic.' '.htmlentities(basename($dir)).'</a></p>';
  212.                                         $count++;
  213.                                 }
  214.  
  215.                                 $files = array_merge(
  216.                                         glob($file.'/'.'*.htm*'), // TODO: also PHP?
  217.                                         glob($file.'/'.'*.url')
  218.                                 );
  219.                                 natcasesort($files);
  220.                                 foreach ($files as $file) {
  221.                                         if (substr($file,-4,4) == '.url') {
  222.                                                 $icon_candidate = pathinfo($file)['dirname'].'/'.pathinfo($file)['filename'].'_tree.png';
  223.                                                 if (file_exists($icon_candidate)) {
  224.                                                         $tree_icon = $icon_candidate;
  225.                                                 } else if (file_exists(__DIR__.'/treeicon_leaf_url.png')) {
  226.                                                         $tree_icon = OIDplus::webpath(__DIR__).'treeicon_leaf_url.png';
  227.                                                 } else {
  228.                                                         $tree_icon = null; // default icon (folder)
  229.                                                 }
  230.                                                 $ic = empty($tree_icon) ? '' : '<img src="'.$tree_icon.'" alt="">';
  231.  
  232.                                                 $hyperlink_pic = ' <img src="'.OIDplus::webpath(__DIR__).'hyperlink.png" widht="13" height="13" alt="Hyperlink" style="top:-3px;position:relative">';
  233.  
  234.                                                 $out['text'] .= '<p><a href="'.htmlentities(self::getHyperlinkURL($file)).'" target="_blank">'.$ic.' '.htmlentities($this->getHyperlinkTitle($file)).' '.$hyperlink_pic.'</a></p>';
  235.                                                 $count++;
  236.                                         } else {
  237.                                                 $icon_candidate = pathinfo($file)['dirname'].'/'.pathinfo($file)['filename'].'_tree.png';
  238.                                                 if (file_exists($icon_candidate)) {
  239.                                                         $tree_icon = $icon_candidate;
  240.                                                 } else if (file_exists(__DIR__.'/treeicon_leaf_doc.png')) {
  241.                                                         $tree_icon = OIDplus::webpath(__DIR__).'treeicon_leaf_doc.png';
  242.                                                 } else {
  243.                                                         $tree_icon = null; // default icon (folder)
  244.                                                 }
  245.                                                 $ic = empty($tree_icon) ? '' : '<img src="'.$tree_icon.'" alt="">';
  246.  
  247.                                                 $out['text'] .= '<p><a '.OIDplus::gui()->link('oidplus:resources$'.$file.'$'.OIDplus::authUtils()::makeAuthKey("resources;$file")).'>'.$ic.' '.htmlentities($this->getDocumentTitle($file)).'</a></p>';
  248.                                                 $count++;
  249.                                         }
  250.                                 }
  251.  
  252.                                 if ($count == 0) {
  253.                                         $out['text'] .= '<p>This folder does not contain any elements</p>';
  254.                                 }
  255.                         } else {
  256.                                 $out['title'] = 'Not found';
  257.                                 $out['icon'] = 'img/error_big.png';
  258.                                 $out['text'] = '<p>This resource doesn\'t exist anymore.</p>';
  259.                                 return $out;
  260.                         }
  261.                 }
  262.         }
  263.  
  264.         private function tree_rec(&$children, $rootdir=null, $depth=0) {
  265.                 if (is_null($rootdir)) $rootdir = OIDplus::config()->getValue('resource_plugin_path', 'res/');
  266.                 if ($depth > 100) return false; // something is wrong!
  267.  
  268.                 $dirs = glob($rootdir.'*'.'/', GLOB_ONLYDIR);
  269.                 natcasesort($dirs);
  270.                 foreach ($dirs as $dir) {
  271.                         $tmp = array();
  272.                         $this->tree_rec($tmp, $dir, $depth+1);
  273.  
  274.                         $icon_candidate = pathinfo($dir)['dirname'].'/'.pathinfo($dir)['filename'].'_tree.png';
  275.                         if (file_exists($icon_candidate)) {
  276.                                 $tree_icon = $icon_candidate;
  277.                         } else if (file_exists(__DIR__.'/treeicon_folder.png')) {
  278.                                 $tree_icon = OIDplus::webpath(__DIR__).'treeicon_folder.png';
  279.                         } else {
  280.                                 $tree_icon = null; // default icon (folder)
  281.                         }
  282.  
  283.                         $children[] = array(
  284.                                 'id' => 'oidplus:resources$'.$dir.'$'.OIDplus::authUtils()::makeAuthKey("resources;$dir"),
  285.                                 'icon' => $tree_icon,
  286.                                 'text' => basename($dir),
  287.                                 'children' => $tmp,
  288.                                 'state' => array("opened" => $depth <= OIDplus::config()->getValue('resource_plugin_autoopen_level', 1)-1)
  289.                         );
  290.                 }
  291.  
  292.                 $files = array_merge(
  293.                         glob($rootdir.'*.htm*'), // TODO: Also PHP?
  294.                         glob($rootdir.'*.url')
  295.                 );
  296.                 natcasesort($files);
  297.                 foreach ($files as $file) {
  298.                         if (substr($file,-4,4) == '.url') {
  299.  
  300.                                 $icon_candidate = pathinfo($file)['dirname'].'/'.pathinfo($file)['filename'].'_tree.png';
  301.                                 if (file_exists($icon_candidate)) {
  302.                                         $tree_icon = $icon_candidate;
  303.                                 } else if (file_exists(__DIR__.'/treeicon_leaf_url.png')) {
  304.                                         $tree_icon = OIDplus::webpath(__DIR__).'treeicon_leaf_url.png';
  305.                                 } else {
  306.                                         $tree_icon = null; // default icon (folder)
  307.                                 }
  308.  
  309.                                 $hyperlink_pic = ' <img src="'.OIDplus::webpath(__DIR__).'hyperlink.png" widht="13" height="13" alt="Hyperlink" style="top:-3px;position:relative">';
  310.  
  311.                                 $children[] = array(
  312.                                         'id' => 'oidplus:resources$'.$file.'$'.OIDplus::authUtils()::makeAuthKey("resources;$file"),
  313.                                         'conditionalselect' => 'window.open('.js_escape(self::getHyperlinkURL($file)).'); false;',
  314.                                         'icon' => $tree_icon,
  315.                                         'text' => $this->getHyperlinkTitle($file).' '.$hyperlink_pic,
  316.                                         'state' => array("opened" => $depth <= OIDplus::config()->getValue('resource_plugin_autoopen_level', 1)-1)
  317.                                 );
  318.  
  319.                         } else {
  320.                                 $icon_candidate = pathinfo($file)['dirname'].'/'.pathinfo($file)['filename'].'_tree.png';
  321.                                 if (file_exists($icon_candidate)) {
  322.                                         $tree_icon = $icon_candidate;
  323.                                 } else if (file_exists(__DIR__.'/treeicon_leaf_doc.png')) {
  324.                                         $tree_icon = OIDplus::webpath(__DIR__).'treeicon_leaf_doc.png';
  325.                                 } else {
  326.                                         $tree_icon = null; // default icon (folder)
  327.                                 }
  328.                                 $children[] = array(
  329.                                         'id' => 'oidplus:resources$'.$file.'$'.OIDplus::authUtils()::makeAuthKey("resources;$file"),
  330.                                         'icon' => $tree_icon,
  331.                                         'text' => $this->getDocumentTitle($file),
  332.                                         'state' => array("opened" => $depth <= OIDplus::config()->getValue('resource_plugin_autoopen_level', 1)-1)
  333.                                 );
  334.                         }
  335.                 }
  336.         }
  337.  
  338.         public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
  339.                 $children = array();
  340.  
  341.                 $this->tree_rec($children, OIDplus::config()->getValue('resource_plugin_path', 'res/'));
  342.  
  343.                 if (!OIDplus::config()->getValue('resource_plugin_hide_empty_path', true) || (count($children) > 0)) {
  344.                         if (file_exists(__DIR__.'/treeicon.png')) {
  345.                                 $tree_icon = OIDplus::webpath(__DIR__).'treeicon.png';
  346.                         } else {
  347.                                 $tree_icon = null; // default icon (folder)
  348.                         }
  349.  
  350.                         $json[] = array(
  351.                                 'id' => 'oidplus:resources$'.OIDplus::config()->getValue('resource_plugin_path', 'res/').'$'.OIDplus::authUtils()::makeAuthKey("resources;".OIDplus::config()->getValue('resource_plugin_path', 'res/')),
  352.                                 'icon' => $tree_icon,
  353.                                 'state' => array("opened" => true),
  354.                                 'text' => OIDplus::config()->getValue('resource_plugin_title', 'Documents and resources'),
  355.                                 'children' => $children
  356.                         );
  357.                 }
  358.  
  359.                 return true;
  360.         }
  361.  
  362.         public function tree_search($request) {
  363.                 return false;
  364.         }
  365.  
  366.         private static function getHyperlinkTitle($file) {
  367.                 return preg_replace('/\\.[^.\\s]{3,4}$/', '', basename($file));
  368.         }
  369.  
  370.         private static function getHyperlinkURL($file) {
  371.                 /*
  372.                 [{000214A0-0000-0000-C000-000000000046}]
  373.                 Prop3=19,2
  374.                 [InternetShortcut]
  375.                 URL=http://www.example.com/
  376.                 IDList=
  377.                 */
  378.                 $cont = file_get_contents($file);
  379.                 if (!preg_match('@URL=(.+)\n@ismU', $cont, $m)) return null;
  380.                 return trim($m[1]);
  381.         }
  382. }
  383.