Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet
[openemr.git] / phpmyadmin / libraries / navigation / Nodes / Node.class.php
bloba1f0e3b442c5dc85f928ed431e24c4ee36f60c33
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Functionality for the navigation tree in the left frame
6 * @package PhpMyAdmin-Navigation
7 */
8 if (! defined('PHPMYADMIN')) {
9 exit;
12 /**
13 * The Node is the building block for the collapsible navigation tree
15 * @package PhpMyAdmin-Navigation
17 class Node
19 /**
20 * @var int Defines a possible node type
22 const CONTAINER = 0;
24 /**
25 * @var int Defines a possible node type
27 const OBJECT = 1;
29 /**
30 * @var string A non-unique identifier for the node
31 * This may be trimmed when grouping nodes
33 public $name = "";
35 /**
36 * @var string A non-unique identifier for the node
37 * This will never change after being assigned
39 public $real_name = "";
41 /**
42 * @var int May be one of CONTAINER or OBJECT
44 public $type = Node::OBJECT;
46 /**
47 * @var bool Whether this object has been created while grouping nodes
48 * Only relevant if the node is of type CONTAINER
50 public $is_group;
52 /**
53 * @var bool Whether to add a "display: none;" CSS
54 * rule to the node when rendering it
56 public $visible = false;
58 /**
59 * @var Node A reference to the parent object of
60 * this node, NULL for the root node.
62 public $parent;
64 /**
65 * @var array An array of Node objects that are
66 * direct children of this node
68 public $children = array();
70 /**
71 * @var Mixed A string used to group nodes, or an array of strings
72 * Only relevant if the node is of type CONTAINER
74 public $separator = '';
76 /**
77 * @var int How many time to recursively apply the grouping function
78 * Only relevant if the node is of type CONTAINER
80 public $separator_depth = 1;
82 /**
83 * @var string An IMG tag, used when rendering the node
85 public $icon;
87 /**
88 * @var Array An array of A tags, used when rendering the node
89 * The indexes in the array may be 'icon' and 'text'
91 public $links;
93 /**
94 * @var string Extra CSS classes for the node
96 public $classes = '';
98 /**
99 * @var string Whether this node is a link for creating new objects
101 public $isNew = false;
104 * @var int The position for the pagination of
105 * the branch at the second level of the tree
107 public $pos2 = 0;
110 * @var int The position for the pagination of
111 * the branch at the third level of the tree
113 public $pos3 = 0;
116 * Initialises the class by setting the mandatory variables
118 * @param string $name An identifier for the new node
119 * @param int $type Type of node, may be one of CONTAINER or OBJECT
120 * @param bool $is_group Whether this object has been created
121 * while grouping nodes
123 * @return Node
125 public function __construct($name, $type = Node::OBJECT, $is_group = false)
127 if (! empty($name)) {
128 $this->name = $name;
129 $this->real_name = $name;
131 if ($type === Node::CONTAINER) {
132 $this->type = Node::CONTAINER;
134 $this->is_group = (bool)$is_group;
138 * Adds a child node to this node
140 * @param Node $child A child node
142 * @return nothing
144 public function addChild($child)
146 $this->children[] = $child;
147 $child->parent = $this;
151 * Returns a child node given it's name
153 * @param string $name The name of requested child
154 * @param bool $real_name Whether to use the "real_name"
155 * instead of "name" in comparisons
157 * @return false|Node The requested child node or false,
158 * if the requested node cannot be found
160 public function getChild($name, $real_name = false)
162 if ($real_name) {
163 foreach ($this->children as $child) {
164 if ($child->real_name == $name) {
165 return $child;
168 } else {
169 foreach ($this->children as $child) {
170 if ($child->name == $name) {
171 return $child;
175 return false;
179 * Removes a child node from this node
181 * @param string $name The name of child to be removed
183 * @return nothing
185 public function removeChild($name)
187 foreach ($this->children as $key => $child) {
188 if ($child->name == $name) {
189 unset($this->children[$key]);
190 break;
196 * Retreives the parents for a node
198 * @param bool $self Whether to include the Node itself in the results
199 * @param bool $containers Whether to include nodes of type CONTAINER
200 * @param bool $groups Whether to include nodes which have $group == true
202 * @return array An array of parent Nodes
204 public function parents($self = false, $containers = false, $groups = false)
206 $parents = array();
207 if ($self
208 && ($this->type != Node::CONTAINER || $containers)
209 && ($this->is_group != true || $groups)
211 $parents[] = $this;
212 $self = false;
214 $parent = $this->parent;
215 while (isset($parent)) {
216 if ( ($parent->type != Node::CONTAINER || $containers)
217 && ($parent->is_group != true || $groups)
219 $parents[] = $parent;
221 $parent = $parent->parent;
223 return $parents;
227 * Returns the actual parent of a node. If used twice on an index or columns
228 * node, it will return the table and database nodes. The names of the returned
229 * nodes can be used in SQL queries, etc...
231 * @return Node
233 public function realParent()
235 $retval = $this->parents();
236 if (count($retval) > 0) {
237 return $retval[0];
238 } else {
239 return false;
244 * This function checks if the node has children nodes associated with it
246 * @param bool $count_empty_containers Whether to count empty child
247 * containers as valid children
249 * @return bool Whether the node has child nodes
251 public function hasChildren($count_empty_containers = true)
253 $retval = false;
254 if ($count_empty_containers) {
255 if (count($this->children)) {
256 $retval = true;
258 } else {
259 foreach ($this->children as $child) {
260 if ($child->type == Node::OBJECT || $child->hasChildren(false)) {
261 $retval = true;
262 break;
266 return $retval;
270 * Returns true the node has some siblings (other nodes on the same tree level,
271 * in the same branch), false otherwise. The only exception is for nodes on
272 * the third level of the tree (columns and indexes), for which the function
273 * always returns true. This is because we want to render the containers
274 * for these nodes
276 * @return bool
278 public function hasSiblings()
280 $retval = false;
281 $paths = $this->getPaths();
282 if (count($paths['aPath_clean']) > 3) {
283 $retval = true;
284 } else {
285 foreach ($this->parent->children as $child) {
286 if ($child != $this
287 && ($child->type == Node::OBJECT || $child->hasChildren(false))
289 $retval = true;
290 break;
294 return $retval;
298 * Returns the number of child nodes that a node has associated with it
300 * @return int The number of children nodes
302 public function numChildren()
304 $retval = 0;
305 foreach ($this->children as $child) {
306 if ($child->type == Node::OBJECT) {
307 $retval++;
308 } else {
309 $retval += $child->numChildren();
312 return $retval;
316 * Returns the actual path and the virtual paths for a node
317 * both as clean arrays and base64 encoded strings
319 * @return array
321 public function getPaths()
323 $aPath = array();
324 $aPath_clean = array();
325 foreach ($this->parents(true, true, false) as $parent) {
326 $aPath[] = base64_encode($parent->real_name);
327 $aPath_clean[] = $parent->real_name;
329 $aPath = implode('.', array_reverse($aPath));
330 $aPath_clean = array_reverse($aPath_clean);
332 $vPath = array();
333 $vPath_clean = array();
334 foreach ($this->parents(true, true, true) as $parent) {
335 $vPath[] = base64_encode($parent->name);
336 $vPath_clean[] = $parent->name;
338 $vPath = implode('.', array_reverse($vPath));
339 $vPath_clean = array_reverse($vPath_clean);
341 return array(
342 'aPath' => $aPath,
343 'aPath_clean' => $aPath_clean,
344 'vPath' => $vPath,
345 'vPath_clean' => $vPath_clean
350 * Returns the names of children of type $type present inside this container
351 * This method is overridden by the Node_Database and Node_Table classes
353 * @param string $type The type of item we are looking for
354 * ('tables', 'views', etc)
355 * @param int $pos The offset of the list within the results
356 * @param string $searchClause A string used to filter the results of the query
358 * @return array
360 public function getData($type, $pos, $searchClause = '')
362 // @todo obey the DisableIS directive
363 $query = "SELECT `SCHEMA_NAME` ";
364 $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` ";
365 $query .= $this->_getWhereClause($searchClause);
366 $query .= "ORDER BY `SCHEMA_NAME` ASC ";
367 $query .= "LIMIT $pos, {$GLOBALS['cfg']['MaxNavigationItems']}";
368 return PMA_DBI_fetch_result($query);
372 * Returns the comment associated with node
373 * This method should be overridden by specific type of nodes
375 * @return string
377 public function getComment()
379 return '';
383 * Returns the number of children of type $type present inside this container
384 * This method is overridden by the Node_Database and Node_Table classes
386 * @param string $type The type of item we are looking for
387 * ('tables', 'views', etc)
388 * @param string $searchClause A string used to filter the results of the query
390 * @return int
392 public function getPresence($type = '', $searchClause = '')
394 if (! $GLOBALS['cfg']['Servers'][$GLOBALS['server']]['DisableIS']) {
395 $query = "SELECT COUNT(*) ";
396 $query .= "FROM `INFORMATION_SCHEMA`.`SCHEMATA` ";
397 $query .= $this->_getWhereClause($searchClause);
398 $retval = (int)PMA_DBI_fetch_value($query);
399 } else {
400 $query = "SHOW DATABASES ";
401 if (! empty($searchClause)) {
402 $query .= "LIKE '%";
403 $query .= PMA_Util::sqlAddSlashes(
404 $searchClause, true
406 $query .= "%' ";
408 $retval = PMA_DBI_num_rows(PMA_DBI_try_query($query));
410 return $retval;
414 * Returns the WHERE clause depending on the $searchClause parameter
415 * and the hide_db directive
417 * @param string $searchClause A string used to filter the results of the query
419 * @return string
421 private function _getWhereClause($searchClause = '')
423 $whereClause = "WHERE TRUE ";
424 if (! empty($searchClause)) {
425 $whereClause .= "AND `SCHEMA_NAME` LIKE '%";
426 $whereClause .= PMA_Util::sqlAddSlashes(
427 $searchClause, true
429 $whereClause .= "%' ";
432 if (! empty($GLOBALS['cfg']['Server']['hide_db'])) {
433 $whereClause .= "AND `SCHEMA_NAME` NOT REGEXP '"
434 . $GLOBALS['cfg']['Server']['hide_db'] . "' ";
437 if (! empty($GLOBALS['cfg']['Server']['only_db'])) {
438 if (is_string($GLOBALS['cfg']['Server']['only_db'])) {
439 $GLOBALS['cfg']['Server']['only_db'] = array(
440 $GLOBALS['cfg']['Server']['only_db']
443 $whereClause .= "AND (";
444 $subClauses = array();
445 foreach ($GLOBALS['cfg']['Server']['only_db'] as $each_only_db) {
446 $subClauses[] = " `SCHEMA_NAME` LIKE '"
447 . $each_only_db . "' ";
449 $whereClause .= implode("OR", $subClauses) . ")";
451 return $whereClause;