1<?php 2/** 3 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 4 * @author Myron Turner <turnermm02@shaw.ca> 5 */ 6// must be run within Dokuwiki 7if(!defined('DOKU_INC')) die(); 8 9if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 10if(!defined('DW_COMMITS')) define('DW_COMMITS',DOKU_INC.'lib/plugins/dwcommits/'); 11global $dwc_dbg_log; 12 13class helper_plugin_dwcommits extends DokuWiki_Plugin { 14 15 private $path; 16 private $status_message; 17 private $branches; 18 private $selected_branch ='master'; 19 private $sqlite; 20 private $git = '/usr/bin/git'; 21 private $repros; 22 private $default_repro; 23 private $db_name; 24 private $remote_url; 25 private $commit_url; 26 27 function __construct() { 28 global $dwc_dbg_log; 29 if(isset($_REQUEST['dwc__repro']) && $_REQUEST['dwc__repro']) { 30 $this->path = $_REQUEST['dwc__repro']; 31 } 32 else { 33 $this->path = $this->get_conf_repro(); 34 } 35 $this->default_repro = $this->path; 36 $this->status_message = array(); 37 $this->selected_branch=""; 38 $this->sqlite = 0; 39 $binary = $this->getConf('git_binary'); 40 if(isset($binary)) $this->git=$binary; 41 $fname_hash = md5($this->path); 42 $names_fname = dirname(__FILE__).'/db/dbnames.ser'; 43 44 if(file_exists($names_fname)) { 45 $inf_str = file_get_contents ($names_fname); 46 $inf = unserialize($inf_str); 47 if($inf[$fname_hash]) { 48 $this->db_name=$inf[$fname_hash]; 49 $this->remote_url=$this->set_githubURL(); 50 } 51 else { 52 $this->db_name=$this->new_dbname($fname_hash,$names_fname,$inf); 53 } 54 } 55 else { 56 $this->db_name=$this->new_dbname($fname_hash,$names_fname, false); 57 } 58 $dwc_dbg_log = DW_COMMITS . 'dwc_debug.log'; 59 60 } 61 62 function new_dbname($fname_hash,$names_fname,$inf_array) { 63 64 if($inf_array && $inf_array['count']) { 65 $count = $inf_array['count'] + 1; 66 } 67 else { 68 $count = 1; 69 $inf_array=array(); 70 } 71 $inf_array['count'] = $count; 72 $new_fname = 'dwcommits_' . $count; 73 $inf_array[$fname_hash] = $new_fname; 74 $inf_array['git' . $count] = $this->path; 75 file_put_contents($names_fname, serialize($inf_array)); 76 return $new_fname ; 77 78 } 79 80 function save_dbnames_ser($fname,$content) { 81 if(function_exists(io_saveFile)){ 82 return io_saveFile($fname,$content); 83 } 84 else { 85 return file_put_contents($names_fname, $content); 86 } 87 } 88 89 function set_githubURL($remote_url="") { 90 $names_fname = dirname(__FILE__).'/db/dbnames.ser'; 91 $inf_str = file_get_contents ($names_fname); 92 $inf = unserialize($inf_str); 93 if(!$inf) return; 94 $fname_hash = md5($this->path); 95 if(!$inf[$fname_hash]) return; 96 $db = $inf[$fname_hash]; 97 list($base,$count) = explode('_',$db); 98 $slot = 'url'.$count; 99 if($remote_url) { 100 $inf[$slot] = $remote_url; 101 if($this->save_dbnames_ser($names_fname,serialize($inf))) { 102 return "$remote_url saved"; 103 } 104 else $this->error(5); 105 } 106 else { 107 if($inf[$slot]) return $inf[$slot]; 108 } 109 110 return ""; 111 112 } 113 114 function current_dbname() { 115 return $this->db_name; 116 } 117 118 /* must be called from syntax.php before _getDB() */ 119 function setup_syntax($name) { 120 $this->db_name = $name; 121 $names_fname = dirname(__FILE__).'/db/dbnames.ser'; 122 $inf_str = file_get_contents ($names_fname); 123 $inf = unserialize($inf_str); 124 if(!$inf) return; 125 126 list($base,$count) = explode('_',$this->db_name); 127 $slot = 'url'.$count; 128 if($inf[$slot]) { 129 $this->remote_url = $inf[$slot]; 130 } 131 else $this->remote_url = ""; 132 return $this->remote_url . " slot=$slot"; 133 } 134 135 136 function get_conf_repro(){ 137 $repro = $this->getConf('default_git'); 138 if(isset($repro) && $repro) { 139 return $repro; 140 } 141 else { 142 return DW_COMMITS . 'db/dokuwiki'; 143 } 144 } 145 146 /** 147 * load the sqlite helper 148 */ 149 function _getDB(){ 150 static $db = null; 151 if ($db === null) { 152 $db =& plugin_load('helper', 'sqlite'); 153 if ($db === null) { 154 msg('The data plugin needs the sqlite plugin', -1); 155 return false; 156 } 157 158 if(!$db->init($this->db_name,dirname(__FILE__).'/db/')){ 159 return false; 160 } 161 if(defined('DOKU_SQLITE_ASSOC')) 162 $db->fetchmode = DOKU_SQLITE_ASSOC; 163 else $db->fetchmode = 'DOKU_SQLITE_ASSOC'; 164 } 165 $this->sqlite = $db; 166 return $db; 167 } 168 function wearehere() { 169 echo 'wearehere'; 170 } 171 172 function chdir() { 173 if(!chdir($this->path)) { 174 if(file_exists($this->path)) { 175 $this->error(1); 176 } 177 else $this->error(0); 178 return false; 179 } 180 return true; 181 } 182 183 function update_commits($which) { 184 $this->status_message = array(); 185 if(!$this->chdir()) return false; 186 187 if($which == 'fetch') { 188 exec("$this->git fetch origin",$retv,$exit_code); 189 $status = "exit code: " . $exit_code . " "; 190 $this->status_message = array_merge(array(getcwd(),"$this->git fetch origin", $status),$this->status_message,$retv); 191 } 192 elseif($which == 'merge') { 193 exec("$this->git merge origin",$retv, $exit_code); 194 $status = "exit code: " . $exit_code; 195 $this->status_message = array_merge(array(getcwd(),"$this->git merge origin", $status),$this->status_message,$retv); 196 } 197 elseif($which == 'commit') { 198 exec("git commit -mdbupgrade",$retv, $exit_code); 199 $status = "exit code: " . $exit_code; 200 $this->status_message = array_merge(array(getcwd(),"git commit", $status),$this->status_message,$retv); 201 if($exit_code <=1 ) return true; 202 } 203 elseif($which == 'add') { 204 exec("$this->git add .",$retv_add, $exit_code); 205 $status = "exit code: " . $exit_code; 206 $this->status_message = array_merge(array(getcwd(),"git add . ", $status),$this->status_message,$retv_add); 207 } 208 elseif($which == 'pull') { 209 exec("$this->git pull",$retv, $exit_code); 210 $status = "exit code: " . $exit_code; 211 $this->status_message = array_merge(array(getcwd(),"git pull", $status),$this->status_message,$retv); 212 } 213 elseif($which == 'branch') { 214 $branch = $_REQUEST['dwc__branch']; 215 exec("$this->git checkout $branch",$retv, $exit_code); 216 $status = "exit code: " . $exit_code; 217 $this->status_message = array_merge(array(getcwd(),"git checkout $branch", $status),$this->status_message,$retv); 218 $this->set_branches(); 219 } 220 elseif($which == 'remote_url') { 221 exec("$this->git config --get remote.origin.url",$retv, $exit_code); 222 $this->remote_url = $retv[0]; 223 $this->remote_url = preg_replace('/:(?!\/)/',"/",$this->remote_url); 224 $this->remote_url = preg_replace('/^\s*.*?@/',"",$this->remote_url); 225 if(!preg_match('/http/',$this->remote_url)) { 226 if(preg_match('/github/',$this->remote_url)) { 227 $this->remote_url = 'https://'. $this->remote_url; 228 } 229 else $this->remote_url = 'http://'. $this->remote_url; 230 } 231 232 $this->status_message = array_merge(array(getcwd(),"git checkout $branch", $status),$this->status_message,$retv); 233 if($this->remote_url) { 234 $this->status_message[] = "Remote URL: $this->remote_url"; 235 } 236 } 237 if($exit_code > 0) return false; 238 return true; 239 240 } 241 242 function set_commit_url() { 243 if(!$this->remote_url) return false; 244 if($this->commit_url) return $this->commit_url; 245 $url = preg_replace('/\.git$/',"", $this->remote_url) . '/commit/'; 246 $this->commit_url=$url; 247 return $url; 248 } 249 250 function get_remote_url() { 251 return $this->remote_url; 252 } 253 254 function set_repros() { 255 $this->repros = array(); 256 $this->repros[] = $this->html_option($this->path,true); 257 $conf_repro = $this->get_conf_repro(); 258 if($this->path != $conf_repro) { 259 $this->repros[] = $this->html_option($conf_repro); 260 } 261 if(file_exists(DOKU_PLUGIN . 'dwcommits/conf/default.local.ini')) { 262 $ini_array = parse_ini_file(DOKU_PLUGIN . 'dwcommits/conf/default.local.ini', true); 263 foreach ($ini_array as $name=>$a) { 264 if($name == 'other_gits') { 265 foreach($a as $git_dir) { 266 $this->repros[] = $this->html_option($git_dir); 267 } 268 } 269 if($name == 'dwc_gits') { 270 foreach($a as $git_dir) { 271 $this->repros[] = $this->html_option(DW_COMMITS_DB . $git_dir); 272 } 273 } 274 } 275 } 276 } 277 278 function get_repros() { 279 echo implode("\n",$this->repros); 280 } 281 282 function set_branches() { 283 if(!$this->chdir()) return false; 284 $this->branches = array(); 285 exec("$this->git branch",$retv, $exit_code); 286 if($exit_code) return false; 287 foreach ($retv as $branch) { 288 if(preg_match('/\*(.*)/',$branch,$matches)) { 289 $this->selected_branch = $matches[1]; 290 $this->branches[] = $this->html_option($matches[1],true); 291 } 292 else { 293 $this->branches[] = $this->html_option($branch); 294 } 295 } 296 } 297 298 function html_option($val, $selected=false) { 299 $val = trim($val); 300 if(!$selected) { 301 return '<option value="'. $val .'">' . $val .'</option>'; 302 } 303 return '<option value="' .$val . '" selected>' . $val . '</option>'; 304 } 305 306 function get_branches() { 307 echo implode("\n",$this->branches); 308 } 309 310 function selected_branch() { 311 if($this->selected_branch) return $this->selected_branch; 312 $this->selected_branch = 'master'; //needed for db column if and when implemented 313 return 'master'; 314 } 315 316 function selected_repro() { 317 if(isset($_REQUEST['dwc__repro']) && $_REQUEST['dwc__repro']) return $_REQUEST['dwc__repro']; 318 return $this->default_repro; 319 } 320 321 /* Seems git status sometimes returns exit code of 1 even when 0 is expected 322 So exit code > 0 can't be trusted to report genuine error. Confirmed via Google 323 */ 324 function get_status() { 325 $this->status_message = array(); 326 if(!$this->chdir()) return false; 327 exec("$this->git status",$retv, $exit_code); 328 $this->status_message = 329 array_merge(array(getcwd(),"git status"),$this->status_message,$retv); 330 return true; 331 332 } 333 334 function error($which, $type=-1) { 335 $path = $this->path; 336 $msgs = array( 337 "Cannot find cloned git at $path", // 0 338 "Cannot access $path. The entire directory and all its contents must be read/write for the web server.", // 1 339 "Cannot fetch from github", // 2 340 "Unable to merge", // 3 341 "Bad Query Construct. Please notify the plugin author.", // 4 342 "Unable to write to dbnames.ser file.", // 5 343 "Please check your query. You seem not to have entered any search terms.", // 6 344 "Unable to restore backup; you may not have a backup saved." // 7 345 ); 346 347 msg($msgs[$which],$type); 348 349 } 350 function get_status_msg() { 351 $status = $this->status_message; 352 $this->status_message = array(); 353 354 $current_git = "<b>Git:</b> $this->path<br/>"; 355 if(!is_array($status)) return $current_git; 356 return $current_git . implode('<br />',$status); 357 358 } 359 360function populate($timestamp_start=0,$table='git_commits') { 361 362 if(!$this->chdir()) return false; 363 364 $months = array('Jan'=>1,'Feb'=>2,'Mar'=>3,'Apr'=>4,'May'=>5,'Jun'=>6,'Jul'=>7, 365 'Aug'=>8,'Sep'=>9,'Oct'=>10,'Nov'=>11,'Dec'=>12); 366 367 $count = 0; 368 $start_number = 0; 369 if(!$timestamp_start) { 370 $timestamp_start = mktime(0,0,0,11,11,2010); 371 } 372 373 $results = $this->sqlite->query("select count(*) from git_commits"); 374 375 $start_number = $this->res2single($results); 376 $since = date('Y-m-d',$timestamp_start); 377 if(!preg_match('/^\d\d\d\d-\d\d-\d\d$/',$since)) { 378 $since = '2010-11-11'; 379 } 380 $handle = popen("$this->git log --since=$since", "r"); 381 $msg = ""; 382 $author=""; 383 $timestamp=0; 384 $gitid=""; 385 $record_done = false; 386 $done = false; 387 if (!$handle) { 388 echo "can't open git\n"; 389 exit; 390 } 391 392 while (($buffer = fgets($handle, 4096)) !== false) { 393 394 395 if(preg_match('/^([A-Z]\w+):(.*)/',$buffer, $matches)) { 396 397 switch($matches[1]){ 398 399 case 'Date': 400 preg_match('/(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)/',$matches[2],$date_matches); 401 list($dstr,$mon,$day,$hour,$min,$sec,$year) = $date_matches; 402 $timestamp = mktime ($hour,$min,$sec, $months[$mon], $day, $year); 403 $count++ ; 404 if($timestamp < $timestamp_start) { 405 $done = true; 406 } 407 break; 408 409 case 'Merge': 410 break; 411 412 case 'Author': 413 $author = $matches[2]; 414 break; 415 416 default: 417 break; 418 } 419 420 } 421 elseif (preg_match('/^commit\s(.*)/',$buffer,$commit)) { 422 if($msg) { 423 $this->insert($author,$timestamp,$gitid,$msg,$table); 424 } 425 $msg = ""; 426 $gitid=$commit[1]; 427 428 } 429 else { 430 $msg .= $buffer; 431 } 432 if($done) break; 433 } 434 435 pclose($handle); 436 $results = $this->sqlite->query("select count(*) from git_commits"); 437 $end_number = $this->res2single($results); 438 439 return array($end_number-$start_number, $end_number); 440 441} 442 443 function insert($author,$timestamp,$gitid,$msg,$table) { 444 445 $prefix = substr( $gitid , 0, 15 ); 446 447 if($this->sqlite->query("INSERT OR IGNORE INTO $table (author,timestamp,gitid,msg,prefix,gitbranch) VALUES (?,?,?,?,?,?)", 448 $author,$timestamp,$gitid,$msg,$prefix,$this->selected_branch)){ 449 return true; 450 } 451 else { 452 return false; 453 } 454 455 } 456 457 458 function select_all($q=array()) { 459 $temp_str = ""; 460 $query = count($q) ? $q: $_REQUEST['dwc_query']; 461 $msg = ""; 462 $author = ""; 463 $branch = ""; 464 $term1 = ""; 465 $term2 = ""; 466 $date_1 = ""; 467 $date_2 = ""; 468 469 foreach($query as $col=>$val) { 470 switch ($col) { 471 case 'author': 472 $author = $this->construct_term('author',$val); 473 break; 474 case 'branch': 475 if($val != 'any') { 476 $branch = $this->construct_term('gitbranch',$val); 477 } 478 break; 479 case 'terms_1': 480 $term1 = $this->construct_term('msg',$val); 481 break; 482 case 'terms_2': 483 $term2 = $this->construct_term('msg',$val); 484 break; 485 case 'd1': 486 $date_1 = $this->get_timestamp($val); 487 break; 488 case 'd2': 489 $date_2 = $this->get_timestamp($val); 490 break; 491 492 } 493 } 494 495 $msg = $this->construct_msg_clause($term1,$term2,$query['OP_1']); 496 $ab_clause = $this->construct_ab_clause($author,$branch,$query['OP_2'],$msg); 497 $attach = ($ab_clause || $msg) ? true : false; 498 $date_clause = $this->construct_date_clause($date_1,$date_2,$attach); 499 $q = $msg . $ab_clause . $date_clause; 500 if(!$q) { 501 $this->error(6,1); 502 return array(); 503 } 504 $res = $this->sqlite->query("SELECT timestamp,author,msg,gitid,gitbranch FROM git_commits WHERE $q ORDER BY timestamp DESC"); 505 if(!$res) { 506 $this->error(4); 507 return false; 508 } 509 510 $arr = $this->sqlite->res2arr($res); 511 if($arr) $q .= " [Rows: " . count($arr) . "] "; 512 return array($arr, $q); 513 514 } 515 516 function format_result_table($arr, $q=false) { 517 518 $this->set_commit_url(); 519 $query = $q ? $q: $_REQUEST['dwc_query']; 520 521 $regex = $this->get_hilite_regex($query); 522 523 $output = ""; 524 foreach($arr as $row) { 525 $output .= $this->format_tablerow($row,$regex); 526 $output .= "<tr><td colspan='3' style='border-bottom: 1px solid black;'>\n"; 527 } 528 return '<table width="85%" cellspacing="4">' . $output . '</table>'; 529 } 530 531 function format_tablerow($row,$regex) { 532 $result = ""; 533 534 $msg = ""; 535 $date = ""; 536 $commit = ""; 537 $branch = ""; 538 $author = ""; 539 global $conf; 540 foreach ($row as $col=>$val) { 541 542 543 if($col == 'msg'){ 544 $msg = hsc($val); 545 if($regex) { 546 $msg = preg_replace($regex,"<span class='dwc_hilite'>$1</span>",$val); 547 } 548 549 } 550 elseif($col == 'timestamp') { 551 $date = date("D M d H:i:s Y" ,$val); 552 } 553 elseif($col == 'gitid') { 554 if($this->commit_url) { 555 $commit = $this->format_commit_url($val); 556 } 557 else $commit = $val; 558 } 559 elseif($col == 'gitbranch') { 560 $branch = $val; 561 } 562 elseif($col == 'author') { 563 list($name,$email) = explode('<',$val); 564 $email = trim($email,'>'); 565 $author = "<a href ='mailto: $email' title='$email'>$name</a>"; 566 } 567 568 569 } 570 571 return "<tr><td rowspan='2'><td nowrap style='padding-right:2px;'>$date</td><td><b>Commit: </b> $commit</td>" . 572 "<tr><td rowspan = '2' valign='top' style='padding-right:2px;'><b>Author: </b>$author<br /><b>Branch: </b>$branch</td>" . 573 "<td style='padding:2px;'>$msg</td>"; 574 575 576 } 577 578 579 function get_hilite_regex($query) { 580 $term1 = $query['terms_1']; 581 $term2 = $query['terms_2']; 582 583 $regex = ""; 584 585 if($term1 && $term2) { 586 $regex = "/($term1|$term2)/ims"; 587 } 588 elseif($term1) { 589 $regex = "/($term1)/ims"; 590 } 591 return $regex; 592 } 593 function format_result_plain($arr, $q=false) { 594 $this->set_commit_url(); 595 $query = $q ? $q: $_REQUEST['dwc_query']; 596 597 $regex = $this->get_hilite_regex($query); 598 599 $output = ""; 600 foreach($arr as $row) { 601 $output .= $this->format_row($row,$regex); 602 $output .= "\n---------\n"; 603 } 604 605 return '<pre>' . $output . '</pre>'; 606 } 607 608 function format_row($row,$regex) { 609 $result = ""; 610 611 foreach ($row as $col=>$val) { 612 613 614 if($col == 'msg'){ 615 $val = wordwrap($val, 80,"\n"); 616 $val = hsc($val); 617 if($regex) { 618 $val = preg_replace($regex,"<span class='dwc_hilite'>$1</span>",$val); 619 } 620 } 621 elseif($col == 'timestamp') { 622 $result .= "<b>Date: </b>"; 623 $val = date("D M d H:i:s Y" ,$val); 624 } 625 elseif($col == 'gitid') { 626 if($this->commit_url) { 627 $result .= 'Commit (URL): '; 628 $result .= $this->format_commit_url($val); 629 continue; 630 } 631 else $result .= '<b>Commit: </b>'; 632 } 633 elseif($col == 'gitbranch') { 634 $result .= '<b>Branch: </b>'; 635 } 636 elseif($col == 'author') { 637 $result .= '<b>Author: </b>'; 638 } 639 else { 640 $result .= "<b>$col: </b>"; 641 } 642 643 $result .= "$val\n"; 644 } 645 return $result; 646 } 647 648 649 function format_commit_url($val) { 650 $url = $this->commit_url . $val; 651 return "<a href='$url' target='commitwin'>$val</a>\n"; 652 } 653 654 function construct_term($col,$val) { 655 if($val) return " $col LIKE '%$val%' "; 656 return ""; 657 } 658 659 function construct_date_clause($d1,$d2, $attach) { 660 $q = ""; 661 $op = $attach ? 'AND' : ""; 662 if($d1 && $d2) { 663 $q = " $op ( timestamp > $d1 AND timestamp < $d2 )"; 664 } 665 elseif($d1) { 666 $q = " $op timestamp > $d1 "; 667 } 668 elseif($d2) { 669 $q = " $op timestamp < $d2 "; 670 } 671 return $q; 672 673 } 674 function construct_ab_clause($author,$branch,$op,$msg){ 675 676 $q = ""; 677 if($author) { 678 if($msg) { 679 $OP = ($op == 'AND') ? ' AND ' : ' OR '; 680 $q = " $OP $author "; 681 } 682 else $q = " $author "; 683 } 684 if($branch) { 685 if($author || $msg){ 686 $q .= " AND $branch "; 687 } 688 else 689 $q = " $branch "; 690 691 } 692 return $q; 693 694 } 695 696 function construct_msg_clause($phrase1,$phrase2,$op) { 697 if(!$phrase1) return ""; 698 if(!$phrase2) return $phrase1; 699 $OP = ($op == 'AND') ? ' AND ' : ' OR '; 700 return " (($phrase1) $OP ($phrase2)) "; 701 } 702 703 function get_timestamp($dstr) { 704 if(!$dstr) return ""; 705 if(preg_match('/[a-zA-Z]/',$dstr)){ 706 msg('Date wasn\'t set:' . $dstr , -1); 707 return false; 708 } 709 710 list($month,$day,$year) = explode('-',$dstr); 711 if((strlen($month) < 2) || (strlen($year) < 4)||(strlen($day) < 2) ) { 712 msg('Incorrect date format: ' . $dstr , -1); 713 } 714 715 if((strlen($month) + strlen($year) + strlen($day) > 8 ) ) { 716 msg('Incorrect date format: ' . $dstr , -1); 717 } 718 719 return mktime (0,0,0, $month, $day, $year); 720 } 721 722 function res2single($res) { 723 if(method_exists($this->sqlite,res2single)){ 724 return $this->sqlite->res2single($res); 725 } 726 $arr = $this->sqlite->res2row($res); 727 list($key,$val) = each($arr); 728 return($val); 729} 730 731function restore_backup() { 732 $names_fname = dirname(__FILE__).'/db/dbnames.ser'; 733 $backup = $names_fname . '.prev'; 734 if(!file_exists($names_fname)) { 735 return "backup file not found"; 736 } 737 if(file_exists($names_fname) && file_exists($backup)) { 738 @unlink($names_fname); 739 } 740 else { 741 $this->error(7); 742 return; 743 } 744 if(rename($backup,$names_fname)) { 745 return "Backup restored"; 746 } 747 748 $this->error(7); 749 return ""; 750} 751 752function prune($del) { 753 $names_fname = dirname(__FILE__).'/db/dbnames.ser'; 754 $msg = ""; 755 $meta = DOKU_INC . 'data/meta/'; 756 if(file_exists($names_fname)) { 757 $inf_str = file_get_contents ($names_fname); 758 $inf = unserialize($inf_str); 759 if(!$inf) return; 760 foreach($_REQUEST[prune] as $db=>$key) { 761 unset($inf[$key]); 762 list($prefix,$index) = explode('_',$db); 763 $url = 'url' . $index; 764 $git = 'git' . $index; 765 if(isset($inf[$url])) { 766 unset($inf[$url]); 767 } 768 if(isset($inf[$git])) { 769 unset($inf[$git]); 770 } 771 772 $sql = $meta . $db . '.sqlite'; 773 if($del && file_exists($sql)) { 774 if(!unlink($sql)) { 775 $msg .= "Could not delete $sql<br />"; 776 777 } 778 } 779 } 780 781 $backup = $names_fname . '.prev'; 782 if(file_exists($backup)) { 783 @unlink($backup); 784 } 785 if(rename($names_fname, $backup)) { 786 $msg .= "Old data saved in backup $backup"; 787 if($del) { 788 $msg .= "<br />This backup may contain references to deleted sqlite dbase files<br />"; 789 } 790 } 791 $this->save_dbnames_ser($names_fname,serialize($inf)); 792 } 793 794 return $msg; 795} 796 797/* Read dbnames.ser and return data found there */ 798function db_data($inf = false) { 799 $output = ""; 800 $filename = DW_COMMITS . 'db/dbnames.ser'; 801 if(!$inf) { 802 $inf_str = file_get_contents ($filename); 803 $inf = unserialize($inf_str); 804 } 805 806 foreach($inf as $val=>$entry) { 807 if(preg_match('/dwcommits_(\d+)/',$entry, $matches)) { 808 $output .= "<b>" . $this->getLang('db_file'). "</b> $entry"; 809 $output .= ' <input type = "checkbox" value = "'. $val. '" name="prune[' .$entry. ']">'; 810 $output .= "<br />"; 811 if(($url = $this->dwc_element('url', $matches[1], $inf))!== false) { 812 $output .= "<b>" . $this->getLang('remote_url'). "</b> $url<br />"; 813 } 814 815 $git = $this->dwc_element('git', $matches[1], $inf); 816 if($git !== false) { 817 if(!file_exists($git)) { 818 $output .= "<b>". $this->getLang('git_missing'). "</b> $git<br />"; 819 } 820 else $output .= "<b>". $this->getLang('git_local'). "</b> $git<br />"; 821 } 822 $output .= "<br />"; 823 } 824 } 825 return $output; 826 } 827 828 function dwc_element($prefix, $suffix, $ar) { 829 $inx = $prefix . $suffix; 830 if(isset($ar[$inx])) { 831 return $ar[$inx]; 832 } 833 return false; 834 835 } 836 837 function recreate_table($timestamp_start) { 838 839 $this->sqlite->query("DROP TABLE git_commits"); 840 $this->sqlite->query('CREATE TABLE git_commits(author TEXT,timestamp INTEGER,gitid TEXT,msg TEXT, prefix TEXT, gitbranch TEXT, PRIMARY KEY(prefix,timestamp))'); 841 $this->populate($timestamp_start); 842 $results = $this->sqlite->query("select count(*) from git_commits"); 843 $res = $this->res2single($results); 844 return $res; 845 846 } 847 848 function write_debug($data) { 849 return; 850 global $dwc_dbg_log; 851 static $handle; 852 if(!$handle) { 853 if(!$handle = fopen($dwc_dbg_log, 'a')) { 854 return; 855 } 856 } 857 if(is_array($data)) $data = print_r($data,true); 858 fwrite($handle, "$data\n"); 859 } 860} 861 862 863