Subversion Repositories oidplus

Rev

Rev 1156 | Rev 1316 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 - 2023 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. namespace ViaThinkSoft\OIDplus;
  21.  
  22. // phpcs:disable PSR1.Files.SideEffects
  23. \defined('INSIDE_OIDPLUS') or die;
  24. // phpcs:enable PSR1.Files.SideEffects
  25.  
  26. class OIDplusMenuUtils extends OIDplusBaseClass {
  27.  
  28.         /**
  29.          * @return string
  30.          * @throws OIDplusConfigInitializationException
  31.          * @throws OIDplusException
  32.          */
  33.         public function nonjs_menu(): string {
  34.                 $json = array();
  35.  
  36.                 $static_node_id = $_REQUEST['goto'] ?? 'oidplus:system';
  37.  
  38.                 foreach (OIDplus::getPagePlugins() as $plugin) {
  39.                         // Note: The system (OIDplusMenuUtils) does only show the menu of
  40.                         //       publicPage plugins. Menu entries for RAs and Admins are
  41.                         //       handled by the tree() function of the plugin publicPages/090_login
  42.                         if (is_subclass_of($plugin, OIDplusPagePluginPublic::class)) {
  43.                                 $plugin->tree($json, null, true, $static_node_id);
  44.                         }
  45.                 }
  46.  
  47.                 $out = '';
  48.                 foreach ($json as $x) {
  49.                         if ($static_node_id == $x['id']) $out .= '<b>';
  50.                         if (isset($x['indent'])) $out .= str_repeat('&nbsp;', $x['indent']*5);
  51.                         $cur_lang = OIDplus::getCurrentLang();
  52.                         if ($cur_lang != OIDplus::getDefaultLang()) {
  53.                                 $out .= '<a href="?lang='.$cur_lang.'&amp;goto='.urlencode($x['id']).'">';
  54.                         } else {
  55.                                 $out .= '<a href="?goto='.urlencode($x['id']).'">';
  56.                         }
  57.                         if (!empty($x['icon'])) $out .= '<img src="'.$x['icon'].'" alt=""> ';
  58.                         $out .= htmlentities($x['id']).' | '.htmlentities($x['text']).'</a><br>';
  59.                         if ($static_node_id == $x['id']) $out .= '</b>';
  60.                 }
  61.                 return $out;
  62.         }
  63.  
  64.         /**
  65.          * @param string $req_id comes from jsTree via AJAX
  66.          * @param string $req_goto comes from the user (GET argument)
  67.          * @return string[]
  68.          */
  69.         public function json_tree(string $req_id, string $req_goto): array {
  70.                 $json = array();
  71.  
  72.                 if ($req_id === '#') {
  73.                         foreach (OIDplus::getPagePlugins() as $plugin) {
  74.                                 // Note: The system (OIDplusMenuUtils) does only show the menu of
  75.                                 //       publicPage plugins. Menu entries for RAs and Admins are
  76.                                 //       handled by the tree() function of the plugin publicPages/090_login
  77.                                 if (is_subclass_of($plugin, OIDplusPagePluginPublic::class)) {
  78.                                         $plugin->tree($json, null, false, $req_goto);
  79.                                 }
  80.                         }
  81.                 } else {
  82.                         $json = $this->tree_populate($req_id);
  83.                 }
  84.  
  85.                 if (is_array($json)) $this->addHrefIfRequired($json);
  86.  
  87.                 return $json;
  88.         }
  89.  
  90.         /**
  91.          * @param array $json
  92.          * @return void
  93.          */
  94.         protected function addHrefIfRequired(array &$json) {
  95.                 foreach ($json as &$item) {
  96.                         if (isset($item['id'])) {
  97.                                 if (!isset($item['conditionalselect']) || ($item['conditionalselect'] != 'false')) {
  98.                                         if (!isset($item['a_attr'])) {
  99.                                                 $item['a_attr'] = array("href" => "?goto=".urlencode($item['id']));
  100.                                         } else if (!isset($item['a_attr']['href'])) {
  101.                                                 $item['a_attr']['href'] = "?goto=".urlencode($item['id']);
  102.                                         }
  103.                                 }
  104.                         }
  105.  
  106.                         if (isset($item['children'])) {
  107.                                 if (is_array($item['children'])) $this->addHrefIfRequired($item['children']);
  108.                         }
  109.                 }
  110.         }
  111.  
  112.         /**
  113.          * @param string $parent
  114.          * @param array|true|null $goto_path
  115.          * @return array
  116.          * @throws OIDplusConfigInitializationException
  117.          * @throws OIDplusException
  118.          */
  119.         public function tree_populate(string $parent, $goto_path=null): array {
  120.                 $children = array();
  121.  
  122.                 $parentObj = OIDplusObject::parse($parent);
  123.  
  124.                 @list($namespace, $oid) = explode(':', $parent, 2);
  125.                 if ($namespace == 'oid') $oid = substr($oid, 1); // Remove leading dot
  126.  
  127.                 if (is_array($goto_path)) array_shift($goto_path);
  128.  
  129.                 $confidential_oids = array();
  130.  
  131.                 $res = OIDplus::db()->query("select id from ###objects where confidential = ?", array(true));
  132.                 while ($row = $res->fetch_array()) {
  133.                         $confidential_oids[] = $row['id'];
  134.                 }
  135.  
  136.                 $res = OIDplus::db()->query("select * from ###objects where parent = ?", array($parent));
  137.                 $res->naturalSortByField('id');
  138.                 while ($row = $res->fetch_array()) {
  139.                         $obj = OIDplusObject::parse($row['id']);
  140.                         if (!$obj) continue; // e.g. object-type plugin disabled
  141.  
  142.                         if (!$obj->userHasReadRights()) continue;
  143.  
  144.                         $child = array();
  145.                         $child['id'] = $row['id'];
  146.  
  147.                         // Determine display name (relative OID)
  148.                         $child['text'] = $parentObj ? $obj->jsTreeNodeName($parentObj) : '';
  149.                         $child['text'] .= empty($row['title']) ? /*' -- <i>'.htmlentities('Title missing').'</i>'*/ '' : ' -- <b>' . htmlentities($row['title']) . '</b>';
  150.  
  151.                         $is_confidential = false;
  152.                         foreach ($confidential_oids as $test) {
  153.                                 $is_confidential |= ($row['id'] === $test) || (strpos($row['id'],$test.'.') === 0);
  154.                         }
  155.                         if ($is_confidential) {
  156.                                 $child['text'] = '<font color="gray"><i>'.$child['text'].'</i></font>';
  157.                         }
  158.  
  159.                         // Determine icon
  160.                         $child['icon'] = $obj->getIcon($row);
  161.  
  162.                         // Check if there are more sub OIDs
  163.                         if ($goto_path === true) {
  164.                                 $child['children'] = $this->tree_populate($row['id'], $goto_path);
  165.                                 $child['state'] = array("opened" => true);
  166.                         } else if (!is_null($goto_path) && (count($goto_path) > 0) && ($goto_path[0] === $row['id'])) {
  167.                                 $child['children'] = $this->tree_populate($row['id'], $goto_path);
  168.                                 $child['state'] = array("opened" => true);
  169.                         } else {
  170.                                 $obj_children = $obj->getChildren();
  171.  
  172.                                 // Variant 1: Fast, but does not check for hidden OIDs
  173.                                 //$child_count = count($obj_children);
  174.  
  175.                                 // variant 2
  176.                                 $child_count = 0;
  177.                                 foreach ($obj_children as $obj_test) {
  178.                                         if (!$obj_test->userHasReadRights()) continue;
  179.                                         $child_count++;
  180.                                 }
  181.  
  182.                                 $child['children'] = $child_count > 0;
  183.                         }
  184.  
  185.                         $children[] = $child;
  186.                 }
  187.  
  188.                 return $children;
  189.         }
  190. }
  191.