1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8//this script may only be included - so its better to die if called directly. 9if (strpos($_SERVER["SCRIPT_NAME"], basename(__FILE__)) !== false) { 10 header("location: index.php"); 11 exit; 12} 13 14/** 15 * 16 */ 17class AdminLib extends TikiLib 18{ 19 20 /** 21 * @param $offset 22 * @param $maxRecords 23 * @param $sort_mode 24 * @param $find 25 * @return array 26 */ 27 function list_dsn($offset, $maxRecords, $sort_mode, $find) 28 { 29 30 $bindvars = []; 31 if ($find) { 32 $findesc = '%' . $find . '%'; 33 34 $mid = " where (`dsn` like ?)"; 35 $bindvars[] = $findesc; 36 } else { 37 $mid = ""; 38 } 39 40 $query = "select * from `tiki_dsn` $mid order by " . $this->convertSortMode($sort_mode); 41 $query_cant = "select count(*) from `tiki_dsn` $mid"; 42 $result = $this->query($query, $bindvars, $maxRecords, $offset); 43 $cant = $this->getOne($query_cant, $bindvars); 44 $ret = []; 45 46 while ($res = $result->fetchRow()) { 47 $ret[] = $res; 48 } 49 50 $retval = []; 51 $retval["data"] = $ret; 52 $retval["cant"] = $cant; 53 return $retval; 54 } 55 56 /** 57 * @param $dsnId 58 * @param $dsn 59 * @param $name 60 * 61 * @return TikiDb_Pdo_Result|TikiDb_Adodb_Result 62 */ 63 function replace_dsn($dsnId, $dsn, $name) 64 { 65 // Check the name 66 if ($dsnId) { 67 $query = "update `tiki_dsn` set `name`=?,`dsn`=? where `dsnId`=?"; 68 $bindvars = [$name, $dsn, $dsnId]; 69 return $this->query($query, $bindvars); 70 } else { 71 $query = "delete from `tiki_dsn`where `name`=? and `dsn`=?"; 72 $bindvars = [$name, $dsn]; 73 $this->query($query, $bindvars); 74 $query = "insert into `tiki_dsn`(`name`,`dsn`) 75 values(?,?)"; 76 return $this->query($query, $bindvars); 77 } 78 } 79 80 /** 81 * @param int $dsnId 82 * 83 * @return TikiDb_Pdo_Result|TikiDb_Adodb_Result 84 */ 85 function remove_dsn($dsnId) 86 { 87 $query = "delete from `tiki_dsn` where `dsnId`=?"; 88 return $this->query($query, [$dsnId]); 89 } 90 91 /** 92 * @param int $dsnId 93 * @return array|bool returns false on failure, or an array of values upon success 94 */ 95 function get_dsn($dsnId) 96 { 97 $query = "select * from `tiki_dsn` where `dsnId`=?"; 98 99 $result = $this->query($query, [$dsnId]); 100 101 if (! $result->numRows()) { 102 return false; 103 } 104 105 $res = $result->fetchRow(); 106 return $res; 107 } 108 109 /** 110 * @param $dsnName 111 * @return array|bool returns false on failure, or an array of values upon success 112 */ 113 function get_dsn_from_name($dsnName) 114 { 115 $query = "select * from `tiki_dsn` where `name`=?"; 116 117 $result = $this->query($query, [$dsnName]); 118 119 if (! $result->numRows()) { 120 return false; 121 } 122 123 $res = $result->fetchRow(); 124 return $res; 125 } 126 127 /** 128 * @param $offset 129 * @param $maxRecords 130 * @param $sort_mode 131 * @param $find 132 * @return array 133 */ 134 function list_extwiki($offset, $maxRecords, $sort_mode, $find) 135 { 136 $bindvars = []; 137 if ($find) { 138 $findesc = '%' . $find . '%'; 139 140 $mid = " where (`extwiki` like ? )"; 141 $bindvars[] = $findesc; 142 } else { 143 $mid = ""; 144 } 145 146 $query = "select * from `tiki_extwiki` $mid order by " . $this->convertSortMode($sort_mode); 147 $query_cant = "select count(*) from `tiki_extwiki` $mid"; 148 $result = $this->fetchAll($query, $bindvars, $maxRecords, $offset); 149 $cant = $this->getOne($query_cant, $bindvars); 150 151 $retval = []; 152 $retval["data"] = $result; 153 $retval["cant"] = $cant; 154 return $retval; 155 } 156 157 /** 158 * @param int $extwikiId 159 * @param string $extwiki 160 * @param $name 161 * @param string $indexName 162 * @param array $groups 163 * 164 * @return array|bool|mixed 165 */ 166 function replace_extwiki($extwikiId, $extwiki, $name, $indexName = '', $groups = []) 167 { 168 $table = $this->table('tiki_extwiki'); 169 $data = [ 170 'name' => $name, 171 'extwiki' => $extwiki, 172 'indexname' => $indexName, 173 'groups' => json_encode(array_values($groups)), 174 ]; 175 $withId = $data; 176 $withId['extwikiId'] = $extwikiId; 177 return $table->insertOrUpdate($withId, $data); 178 } 179 180 /** 181 * Removes a configuration option of an external wiki 182 * 183 * @param $extwikiId int Id of the external wiki to be removed 184 * 185 * @return TikiDb_Pdo_Result|TikiDb_Adodb_Result 186 */ 187 function remove_extwiki($extwikiId) 188 { 189 $query = "delete from `tiki_extwiki` where `extwikiId`=?"; 190 return $this->query($query, [$extwikiId]); 191 } 192 193 /** 194 * @param int $extwikiId 195 * @return bool 196 */ 197 function get_extwiki($extwikiId) 198 { 199 $table = $this->table('tiki_extwiki'); 200 $row = $table->fetchFullRow(['extwikiId' => $extwikiId]); 201 202 if (! empty($row['groups'])) { 203 $row['groups'] = json_decode($row['groups']); 204 } 205 return $row; 206 } 207 208 209 /** 210 * Remove unused wiki attachment pictures 211 */ 212 function remove_unused_pictures() 213 { 214 global $tikidomain; 215 216 $query = "select `data` from `tiki_pages`"; 217 $result = $this->query($query, []); 218 $pictures = []; 219 220 while ($res = $result->fetchRow()) { 221 preg_match_all("/\{(picture |img )([^\}]+)\}/ixs", $res['data'], $pics); //fixme: pick also the picture into ~np~ 222 223 foreach (array_unique($pics[2]) as $pic) { 224 if (preg_match("/(src|file)=\"([^\"]+)\"/xis", $pic, $matches)) { 225 $pictures[] = $matches[2]; 226 } 227 if (preg_match("/(src|file)="([^&]+)"/xis", $pic, $matches)) { 228 $pictures[] = $matches[2]; 229 } 230 if (preg_match("/(src|file)=([^&\"\s,]+)/xis", $pic, $matches)) { 231 $pictures[] = $matches[2]; 232 } 233 } 234 } 235 $pictures = array_unique($pictures); 236 237 $path = "img/wiki_up"; 238 if ($tikidomain) { 239 $path .= "/$tikidomain"; 240 } 241 $h = opendir($path); 242 243 while (($file = readdir($h)) !== false) { 244 if (is_file("$path/$file") && $file != 'license.txt' && $file != 'index.php' && $file != '.cvsignore' && $file != 'README') { 245 $filename = "$path/$file"; 246 247 if (! in_array($filename, $pictures)) { 248 @unlink($filename); 249 } 250 } 251 } 252 253 closedir($h); 254 } 255 256 257 /** 258 * An image gallery function that removes orphaned images. 259 */ 260 261 function remove_orphan_images() 262 { 263 $merge = []; 264 265 // Find images in tiki_pages 266 $query = "select `data` from `tiki_pages`"; 267 $result = $this->query($query, []); 268 269 while ($res = $result->fetchRow()) { 270 preg_match_all("/src=\"([^\"]+)\"/", $res["data"], $reqs1); 271 272 preg_match_all("/src=\'([^\']+)\'/", $res["data"], $reqs2); 273 preg_match_all("/src=([A-Za-z0-9:\?\=\/\.\-\_]+)\}/", $res["data"], $reqs3); 274 $merge = array_merge($merge, $reqs1[1], $reqs2[1], $reqs3[1]); 275 $merge = array_unique($merge); 276 } 277 278 // Find images in Tiki articles 279 $query = "select `body` from `tiki_articles`"; 280 $result = $this->query($query, []); 281 282 while ($res = $result->fetchRow()) { 283 preg_match_all("/src=\"([^\"]+)\"/", $res["body"], $reqs1); 284 285 preg_match_all("/src=\'([^\']+)\'/", $res["body"], $reqs2); 286 preg_match_all("/src=([A-Za-z0-9:\?\=\/\.\-\_]+)\}/", $res["body"], $reqs3); 287 $merge = array_merge($merge, $reqs1[1], $reqs2[1], $reqs3[1]); 288 $merge = array_unique($merge); 289 } 290 291 // Find images in tiki_submissions 292 $query = "select `body` from `tiki_submissions`"; 293 $result = $this->query($query, []); 294 295 while ($res = $result->fetchRow()) { 296 preg_match_all("/src=\"([^\"]+)\"/", $res["body"], $reqs1); 297 298 preg_match_all("/src=\'([^\']+)\'/", $res["body"], $reqs2); 299 preg_match_all("/src=([A-Za-z0-9:\?\=\/\.\-\_]+)\}/", $res["body"], $reqs3); 300 $merge = array_merge($merge, $reqs1[1], $reqs2[1], $reqs3[1]); 301 $merge = array_unique($merge); 302 } 303 304 // Find images in tiki_blog_posts 305 $query = "select `data` from `tiki_blog_posts`"; 306 $result = $this->query($query, []); 307 308 while ($res = $result->fetchRow()) { 309 preg_match_all("/src=\"([^\"]+)\"/", $res["data"], $reqs1); 310 311 preg_match_all("/src=\'([^\']+)\'/", $res["data"], $reqs2); 312 preg_match_all("/src=([A-Za-z0-9:\?\=\/\.\-\_]+)\}/", $res["data"], $reqs3); 313 $merge = array_merge($merge, $reqs1[1], $reqs2[1], $reqs3[1]); 314 $merge = array_unique($merge); 315 } 316 317 $positives = []; 318 319 foreach ($merge as $img) { 320 if (strstr($img, 'show_image')) { 321 preg_match("/id=([0-9]+)/", $img, $rq); 322 323 $positives[] = $rq[1]; 324 } 325 } 326 327 $query = "select `imageId` from `tiki_images` where `galleryId`=0"; 328 $result = $this->query($query, []); 329 330 while ($res = $result->fetchRow()) { 331 $id = $res["imageId"]; 332 333 if (! in_array($id, $positives)) { 334 TikiLib::lib('imagegal')->remove_image($id,$GLOBALS['user']); 335 } 336 } 337 } 338 339 /** 340 * Finds if a name given to a database dump is already in use 341 * 342 * @param string $tag 343 * @return bool false on no tag existing, true on tag already present 344 */ 345 function tag_exists($tag) 346 { 347 $query = "select distinct `tagName` from `tiki_tags` where `tagName` = ?"; 348 349 $result = $this->query($query, [$tag]); 350 return (bool)$result->numRows(); 351 } 352 353 /** 354 * 355 * Removes a database dump 356 * 357 * @param string $tagname 358 * @return bool Right now only returns true 359 */ 360 function remove_tag($tagname) 361 { 362 $query = "delete from `tiki_tags` where `tagName`=?"; 363 $this->query($query, [$tagname]); 364 TikiLib::lib('logs')->add_log('dump', "removed tag: $tagname"); 365 return true; 366 //fixme: This should return false on failure 367 } 368 369 /** 370 * @return array 371 */ 372 function get_tags() 373 { 374 $query = "select distinct `tagName` from `tiki_tags`"; 375 376 $result = $this->query($query, []); 377 $ret = []; 378 379 while ($res = $result->fetchRow()) { 380 $ret[] = $res["tagName"]; 381 } 382 383 return $ret; 384 } 385 386 /** 387 * 388 * This function can be used to store the set of actual pages in the "tags" 389 * table preserving the state of the wiki under a tag name. 390 * @param $tagname 391 * @see dump() 392 */ 393 function create_tag($tagname) 394 { 395 $query = "select * from `tiki_pages`"; 396 $result = $this->query($query, []); 397 398 while ($res = $result->fetchRow()) { 399 $data = $res["data"]; 400 $pageName = $res["pageName"]; 401 $description = $res["description"]; 402 $query = "delete from `tiki_tags`where `tagName`=? and `pageName`=?"; 403 $this->query($query, [$tagname, $pageName], -1, -1, false); 404 $query = "insert into `tiki_tags`(`tagName`,`pageName`,`hits`,`data`,`lastModif`,`comment`,`version`,`user`,`ip`,`flag`,`description`)" . 405 " values(?,?,?,?,?,?,?,?,?,?,?)"; 406 $this->query( 407 $query, 408 [ 409 $tagname, 410 $pageName, 411 $res["hits"], 412 $data, 413 $res["lastModif"], 414 $res["comment"], 415 $res["version"], 416 $res["user"], 417 $res["ip"], 418 $res["flag"], 419 $description 420 ] 421 ); 422 } 423 424 $logslib = TikiLib::lib('logs'); 425 $logslib->add_log('dump', "wiki database dump created: $tagname"); 426 } 427 428 /** 429 * This funcion recovers the state of the wiki using a tagName from the tags table 430 * 431 * @param string $tagname 432 * @return bool currenty only returns true 433 */ 434 function restore_tag($tagname) 435 { 436 437 $query = "update `tiki_pages` set `cache_timestamp`=0"; 438 $this->query($query, []); 439 $query = "select * from `tiki_tags` where `tagName`=?"; 440 $result = $this->query($query, [$tagname]); 441 442 while ($res = $result->fetchRow()) { 443 $query = "update `tiki_pages`" . 444 " set `hits`=?,`data`=?,`lastModif`=?,`comment`=?,`version`=`version`+1,`user`=?,`ip`=?,`flag`=?,`description`=?" . 445 " where `pageName`=?"; 446 447 $this->query( 448 $query, 449 [ 450 $res["hits"], 451 $res["data"], 452 $res["lastModif"], 453 $res["comment"], 454 $res["user"], 455 $res["ip"], 456 $res["flag"], 457 $res["description"], 458 $res["pageName"] 459 ] 460 ); 461 } 462 463 TikiLib::lib('logs')->add_log('dump', "recovered tag: $tagname"); 464 return true; 465 // fixme: should return false on failure 466 } 467 468 /** Dumps wiki pages to a tar file 469 * @see create_tag() 470 */ 471 function dump() 472 { 473 global $tikidomain, $prefs; 474 $parserlib = TikiLib::lib('parser'); 475 476 $dumpPath = "storage"; 477 if ($tikidomain) { 478 $dumpPath .= "/$tikidomain"; 479 } 480 481 $dumpPath = $dumpPath . '/dump_wiki.tar'; 482 @unlink($dumpPath); 483 $tar = new tar(); 484 485 // @fixme: Completely outdated. styles/ no longer exists. 486 //$tar->addFile('styles/' . $prefs['theme']); 487 488 // Foreach page 489 $query = "select * from `tiki_pages`"; 490 $result = $this->query($query, []); 491 492 while ($res = $result->fetchRow()) { 493 $pageName = $res["pageName"] . '.html'; 494 495 $pageContents = $parserlib->parse_data($res["data"]); 496 497 // Now change tiki-index.php?page=foo to foo.html 498 // and tiki-index.php to HomePage.html 499 $pageContents = preg_replace("/tiki-index.php\?page=([^\'\"\$]+)/", "$1.html", $pageContents); 500 $pageContents = preg_replace("/tiki-editpage.php\?page=([^\'\"\$]+)/", "", $pageContents); 501 //preg_match_all("/tiki-index.php\?page=([^ ]+)/",$dat,$cosas); 502 //print_r($cosas); 503 504 $data = "<html>"; 505 $data .= "<head>"; 506 $data .= "<title>" . $res["pageName"] . "</title>"; 507 // $data .= "<link rel='StyleSheet' href='styles/" . $prefs['style'] . "' type='text/css'>"; 508 $data .= '</head>'; 509 $data .= "<body><a class='wiki' href='" . 510 $prefs['wikiHomePage'] . 511 ".html'>home</a><br /><h1>" . 512 $res["pageName"] . 513 "</h1><div class='wikitext'>" . 514 $pageContents . 515 '</div></body>'; 516 $data .= '</html>'; 517 $tar->addData($pageName, $data, $res["lastModif"]); 518 } 519 520 $tar->toTar($dumpPath, false); 521 unset($tar); 522 $logslib = TikiLib::lib('logs'); 523 $logslib->add_log('dump', 'wiki file dump created in ' . $dumpPath); 524 } 525 526 /** 527 * Validates if the php version is fully compatible with OPCache. 528 * @return bool 529 */ 530 function checkOPCacheCompatibility() 531 { 532 return ! ((version_compare(PHP_VERSION, '7.1.0', '>=') && version_compare(PHP_VERSION, '7.2.0', '<')) //7.1.x 533 || (version_compare(PHP_VERSION, '7.2.0', '>=') && version_compare(PHP_VERSION, '7.2.19', '<')) // >= 7.2.0 < 7.2.19 534 || (version_compare(PHP_VERSION, '7.3.0', '>=') && version_compare(PHP_VERSION, '7.3.6', '<'))); // >= 7.3.0 < 7.3.6 535 } 536 537 public function getOpcodeCacheStatus() 538 { 539 $opcode_stats = [ 540 'opcode_cache' => null, 541 'stat_flag' => null, 542 'warning_check' => false, 543 'warning_fresh' => false, 544 'warning_ratio' => false, 545 'warning_starve' => false, 546 'warning_low' => false, 547 'warning_xcache_blocked' => false, 548 ]; 549 550 if (function_exists('apc_sma_info') && ini_get('apc.enabled')) { 551 if ($_REQUEST['apc_clear'] && TikiLib::lib('access')->checkCsrf()) { 552 $results['system'] = apc_clear_cache(); 553 $results['user'] = apc_clear_cache('user'); 554 $results['opcode'] = apc_clear_cache('opcode'); 555 if (! in_array(false, $results, true)) { 556 Feedback::success(tr('APC system, user and opcode caches cleared')); 557 } else { 558 foreach ($results as $resultType => $result) { 559 if ($result === true) { 560 Feedback::success(tr('APC %0 cache cleared', $resultType)); 561 } elseif ($result === false) { 562 Feedback::error(tr('APC %0 cache not cleared', $resultType)); 563 } 564 } 565 } 566 } 567 568 $sma = apc_sma_info(); 569 $mem_total = $sma['num_seg'] * $sma['seg_size']; 570 571 $cache = apc_cache_info(null, true); 572 $hit_total = $cache['num_hits'] + $cache['num_misses']; 573 if (! $hit_total) { // cheat for chart after cache clear 574 $hit_total = 1; 575 $cache['num_misses'] = 1; 576 } 577 578 $opcode_stats = [ 579 'opcode_cache' => 'APC', 580 'stat_flag' => 'apc.stat', 581 'memory_used' => ($mem_total - $sma['avail_mem']) / $mem_total, 582 'memory_avail' => $sma['avail_mem'] / $mem_total, 583 'memory_total' => $mem_total, 584 'hit_hit' => $cache['num_hits'] / $hit_total, 585 'hit_miss' => $cache['num_misses'] / $hit_total, 586 'hit_total' => $hit_total, 587 'type' => 'apc', 588 ]; 589 } elseif (function_exists('xcache_info') && (ini_get('xcache.cacher') == '1' || ini_get('xcache.cacher') == 'On')) { 590 if (ini_get('xcache.admin.enable_auth') == '1' || ini_get('xcache.admin.enable_auth') == 'On') { 591 $opcode_stats['warning_xcache_blocked'] = true; 592 } else { 593 $opcode_stats = [ 594 'stat_flag' => 'xcache.stat', 595 'memory_used' => 0, 596 'memory_avail' => 0, 597 'memory_total' => 0, 598 'hit_hit' => 0, 599 'hit_miss' => 0, 600 'hit_total' => 0, 601 'type' => 'xcache', 602 ]; 603 604 foreach (range(0, xcache_count(XC_TYPE_PHP) - 1) as $index) { 605 $info = xcache_info(XC_TYPE_PHP, $index); 606 607 $opcode_stats['hit_hit'] += $info['hits']; 608 $opcode_stats['hit_miss'] += $info['misses']; 609 $opcode_stats['hit_total'] += $info['hits'] + $info['misses']; 610 611 $opcode_stats['memory_used'] += $info['size'] - $info['avail']; 612 $opcode_stats['memory_avail'] += $info['avail']; 613 $opcode_stats['memory_total'] += $info['size']; 614 } 615 616 $opcode_stats['memory_used'] /= $opcode_stats['memory_total']; 617 $opcode_stats['memory_avail'] /= $opcode_stats['memory_total']; 618 $opcode_stats['hit_hit'] /= $opcode_stats['hit_total']; 619 $opcode_stats['hit_miss'] /= $opcode_stats['hit_total']; 620 } 621 $opcode_stats['opcode_cache'] = 'XCache'; 622 } elseif (function_exists('wincache_fcache_fileinfo')) { 623 // Wincache is installed 624 625 // Determine if version 1 or 2 is used. Version 2 does not support ocache 626 627 if (function_exists('wincache_ocache_fileinfo')) { 628 // Wincache version 1 629 if (ini_get('wincache.ocenabled') == '1') { 630 $opcode_stats = [ 631 'opcode_cache' => 'WinCache', 632 'stat_flag' => 'wincache.ocenabled', 633 'memory_used' => 0, 634 'memory_avail' => 0, 635 'memory_total' => 0, 636 'hit_hit' => 0, 637 'hit_miss' => 0, 638 'hit_total' => 0, 639 'type' => 'wincache', 640 ]; 641 642 $info = wincache_ocache_fileinfo(); 643 } 644 } else { 645 // Wincache version 2 or higher 646 if (ini_get('wincache.fcenabled') == '1') { 647 $opcode_stats = [ 648 'opcode_cache' => 'WinCache', 649 'stat_flag' => 'wincache.fcenabled', 650 'memory_used' => 0, 651 'memory_avail' => 0, 652 'memory_total' => 0, 653 'hit_hit' => 0, 654 'hit_miss' => 0, 655 'hit_total' => 0, 656 'type' => 'wincache', 657 ]; 658 $info = wincache_fcache_fileinfo(); 659 } 660 } 661 if (! empty($opcode_stats['stat_flag'])) { 662 $opcode_stats['hit_hit'] = $info['total_hit_count']; 663 $opcode_stats['hit_miss'] = $info['total_miss_count']; 664 $opcode_stats['hit_total'] = $info['total_hit_count'] + $info['total_miss_count']; 665 666 $memory = wincache_fcache_meminfo(); 667 $opcode_stats['memory_avail'] = $memory['memory_free']; 668 $opcode_stats['memory_total'] = $memory['memory_total']; 669 $opcode_stats['memory_used'] = $memory['memory_total'] - $memory['memory_free']; 670 671 $opcode_stats['memory_used'] /= $opcode_stats['memory_total']; 672 $opcode_stats['memory_avail'] /= $opcode_stats['memory_total']; 673 $opcode_stats['hit_hit'] /= $opcode_stats['hit_total']; 674 $opcode_stats['hit_miss'] /= $opcode_stats['hit_total']; 675 } 676 } elseif (function_exists('opcache_get_status') && ini_get('opcache.enable') == '1') { 677 $opcode_stats['opcode_cache'] = 'OpCache'; 678 $status = opcache_get_status(); 679 680 $opcode_stats['hit_hit'] = $status['opcache_statistics']['hits']; 681 $opcode_stats['hit_miss'] = $status['opcache_statistics']['misses']; 682 $opcode_stats['hit_total'] = $status['opcache_statistics']['hits'] + $status['opcache_statistics']['misses']; 683 684 $opcode_stats['memory_avail'] = $status['memory_usage']['free_memory']; 685 $opcode_stats['memory_used'] = $status['memory_usage']['used_memory']; 686 $opcode_stats['memory_total'] = $status['memory_usage']['used_memory'] + $status['memory_usage']['free_memory']; 687 688 $opcode_stats['memory_used'] /= $opcode_stats['memory_total']; 689 $opcode_stats['memory_avail'] /= $opcode_stats['memory_total']; 690 $opcode_stats['hit_hit'] /= $opcode_stats['hit_total']; 691 $opcode_stats['hit_miss'] /= $opcode_stats['hit_total']; 692 } 693 694 // Make results easier to read 695 $opcode_stats['memory_used'] = round($opcode_stats['memory_used'], 2); 696 $opcode_stats['memory_avail'] = round($opcode_stats['memory_avail'], 2); 697 $opcode_stats['hit_hit'] = round($opcode_stats['hit_hit'], 2); 698 $opcode_stats['hit_miss'] = round($opcode_stats['hit_miss'], 2); 699 700 if (isset($opcode_stats['hit_total'])) { 701 $opcode_stats = array_merge( 702 $opcode_stats, 703 [ 704 'warning_fresh' => $opcode_stats['hit_total'] < 10000, 705 'warning_ratio' => $opcode_stats['hit_hit'] < 0.8, 706 ] 707 ); 708 } 709 710 if (isset($opcode_stats['memory_total'])) { 711 $opcode_stats = array_merge( 712 $opcode_stats, 713 [ 714 'warning_starve' => $opcode_stats['memory_avail'] < 0.2, 715 'warning_low' => $opcode_stats['memory_total'] < 60 * 1024 * 1024, 716 ] 717 ); 718 } 719 720 $stat_flag = $opcode_stats['stat_flag']; 721 if ($stat_flag) { 722 $opcode_stats['warning_check'] = (bool)ini_get($stat_flag); 723 } 724 725 return $opcode_stats; 726 } 727 728 /** 729 * Check if System Configuration file has "ini" extension and is under the tiki installation (likely web accessible) 730 * 731 * @return bool 732 */ 733 public function checkSystemConfigurationFile() 734 { 735 $show_warning = false; 736 737 $db_file = 'db/local.php'; 738 if (file_exists($db_file)) { 739 include($db_file); 740 741 if (isset($system_configuration_file) && file_exists($system_configuration_file)) { 742 $tikiPath = realpath(TIKI_PATH); 743 $configPath = realpath($system_configuration_file); 744 if (strncmp($tikiPath, $configPath, strlen($tikiPath)) == 0) { 745 $file_extension = pathinfo($system_configuration_file, PATHINFO_EXTENSION); 746 if ($file_extension == 'ini') { 747 $show_warning = true; 748 } 749 } 750 } 751 } 752 753 return $show_warning; 754 } 755} 756