Subversion Repositories oidplus

Rev

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