Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/spikephpcoverage/src/remote/RemoteCoverageRecorder.php
Go to the documentation of this file.
00001 <?php
00002     /*
00003     *  $Id: RemoteCoverageRecorder.php,v 1.2 2010/12/14 17:36:05 moodlerobot Exp $
00004     *  
00005     *  Copyright(c) 2004-2006, SpikeSource Inc. All Rights Reserved.
00006     *  Licensed under the Open Software License version 2.1
00007     *  (See http://www.spikesource.com/license.html)
00008     */
00009 ?>
00010 <?php
00011 
00012     if(!defined("__PHPCOVERAGE_HOME")) {
00013         define("__PHPCOVERAGE_HOME", dirname(dirname(__FILE__)));
00014     }
00015     require_once __PHPCOVERAGE_HOME . "/util/Utility.php";
00016     require_once __PHPCOVERAGE_HOME . "/CoverageRecorder.php";
00017     require_once __PHPCOVERAGE_HOME . "/remote/XdebugTraceReader.php";
00018     require_once __PHPCOVERAGE_HOME . "/parser/CoverageXmlParser.php";
00019 
00027     class RemoteCoverageRecorder extends CoverageRecorder {
00028         /*{{{ Members */
00029 
00030         protected $traceFilePath;
00031         protected $xdebugTraceReader;
00032         protected $tmpDir;
00033         protected $tmpTraceFilename = "phpcoverage.xdebug.trace";
00034         protected $coverageFileName = "phpcoverage.coverage.xml";
00035 
00036         protected $xmlStart = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><spike-phpcoverage>";
00037         protected $xmlEnd = "</spike-phpcoverage>";
00038 
00039         /*}}}*/
00040         /*{{{ public function __construct() */
00041 
00047         public function __construct(
00048             $includePaths=array("."),
00049             $excludePaths=array(),
00050             $reporter="new HtmlCoverageReporter()"
00051         ) {
00052             global $util;
00053             parent::__construct($includePaths, $excludePaths, $reporter);
00054             $this->isRemote = true;
00055             $this->phpCoverageFiles[] = "phpcoverage.remote.inc.php";
00056             $this->phpCoverageFiles[] = "phpcoverage.remote.top.inc.php";
00057             $this->phpCoverageFiles[] = "phpcoverage.remote.bottom.inc.php";
00058 
00059             // configuration
00060             $this->tmpDir = $util->getTmpDir();
00061         }
00062 
00063         /*}}}*/
00064         /*{{{ Getters and Setters */
00065 
00066         public function getTraceFilePath() {
00067             return $this->traceFilePath;
00068         }
00069 
00070         public function setTraceFilePath($traceFilePath) {
00071             $this->traceFilePath = $traceFilePath;
00072         }
00073 
00074         public function getTmpDir() {
00075             return $this->tmpDir;
00076         }
00077 
00078         public function setTmpDir($tmpTraceDir) {
00079             $this->tmpDir = $tmpTraceDir;
00080         }
00081 
00082         public function getCoverageFileName() {
00083             return $this->coverageFileName;
00084         }
00085 
00086         public function setCoverageFileName($covFileName) {
00087             $this->coverageFileName = $covFileName;
00088         }
00089 
00090         /*}}}*/
00091         /*{{{ public function cleanCoverageFile() */
00092 
00099         public function cleanCoverageFile() {
00100             $filepath = $this->tmpDir . "/" . $this->coverageFileName;
00101             if(file_exists($filepath)) {
00102                 if(is_writable($filepath)) {
00103                     unlink($filepath);
00104                 }
00105                 else {
00106                     $this->logger->error("[RemoteCoverageRecorder::cleanCoverageFile()] "
00107                     . "ERROR: Cannot delete $filepath.", __FILE__, __LINE__);
00108                     return false;
00109                 }
00110             }
00111             return true;
00112         }
00113 
00114         /*}}}*/
00115         /*{{{ protected function prepareCoverageXml() */
00116 
00123         protected function prepareCoverageXml() {
00124             global $util;
00125             $xmlString = "";
00126             $xmlBody = "";
00127             if(!empty($this->coverageData)) {
00128                 foreach($this->coverageData as $file => &$lines) {
00129                     $xmlBody .= "<file path=\"". $util->replaceBackslashes($file) . "\">";
00130                     foreach($lines as $linenum => &$frequency) {
00131                         $xmlBody .= "<line line-number=\"" . $linenum . "\"";
00132                         $xmlBody .= " frequency=\"" . $frequency . "\"/>";
00133                     }
00134                     $xmlBody .= "</file>\n";
00135                 }
00136                 unset($this->coverageData);
00137             }
00138             else {
00139                 $this->logger->info("[RemoteCoverageRecorder::prepareCoverageXml()] Coverage data is empty.",
00140                     __FILE__, __LINE__);
00141             }
00142             $xmlString .= $xmlBody;
00143             $this->logger->debug("[RemoteCoverageRecorder::prepareCoverageXml()] Xml: " . $xmlString, __FILE__, __LINE__);
00144             return $xmlString;
00145         }
00146 
00147         /*}}}*/
00148         /*{{{ protected function parseCoverageXml() */
00149 
00158         protected function parseCoverageXml(&$xml, $stream=false) {
00159             // Need to handle multiple xml files.
00160             if(!is_array($xml)) {
00161                 $xml = array($xml);
00162             }
00163             for($i = 0; $i < count($xml); $i++) {
00164                 $xmlParser = new CoverageXmlParser();
00165                 if($stream) {
00166                     $xmlParser->setInput($xml[$i]);
00167                 }
00168                 else {
00169                     $xmlParser->setInputString($xml[$i]);
00170                 }
00171                 $xmlParser->parse();
00172                 $data =& $xmlParser->getCoverageData();
00173                 if(empty($this->coverageData)) {
00174                     $this->coverageData = $data;
00175                 }
00176                 else {
00177                     $data2 = array_merge_recursive($this->coverageData, $data);
00178                     $this->coverageData = $data2;
00179                 }
00180                 $this->logger->debug("[RemoteCoverageRecorder::prepareCoverageXml()] " . "Coverage data intermediate: " . print_r($this->coverageData, true));
00181             }
00182         }
00183 
00184         /*}}}*/
00185         /*{{{ public function getCoverageXml() */
00186 
00192         public function getCoverageXml() {
00193             $filepath = $this->tmpDir . "/" . $this->coverageFileName;
00194             if(file_exists($filepath) && is_readable($filepath)) {
00195                 $fp = fopen($filepath, "r");
00196                 if($fp) {
00197                     while(!feof($fp)) {
00198                         $xml = fread($fp, 4096);
00199                         echo $xml;
00200                     }
00201                     fclose($fp);
00202                     return true;
00203                 }
00204                 else {
00205                     $this->logger->error("Could not read coverage data file.",
00206                         __FILE__, __LINE__);
00207                 }
00208             }
00209             else {
00210                 $this->logger->error("[RemoteCoverageRecorder::getCoverageXml()] " 
00211                 . "ERROR: Cannot read file " . $filepath, __FILE__, __LINE__);
00212             }
00213             return false;
00214         }
00215 
00216         /*}}} */
00217         /*{{{ protected function appendDataToFile() */
00218 
00226         protected function appendDataToFile($newXml) {
00227             $filepath = $this->tmpDir . "/" . $this->coverageFileName;
00228             if(!file_exists($filepath)) {
00229                 // If new file, write the xml start and end tags
00230                 $bytes = file_put_contents($filepath, $this->xmlStart . "\n" . $this->xmlEnd);
00231                 if(!$bytes) {
00232                     $this->logger->critical("[RemoteCoverageRecorder::appendDataToFile()] Could not create file: " . $filepath, __FILE__, __LINE__);
00233                     return false;
00234                 }
00235             }
00236             if(file_exists($filepath) && is_readable($filepath)) {
00237                 $res = fopen($filepath, "r+");
00238                 if($res) {
00239                     fseek($res, -1 * strlen($this->xmlEnd), SEEK_END);
00240                     $ret = fwrite($res, $newXml);
00241                     if(!$ret) {
00242                         $this->logger->error("[RemoteCoverageRecorder::appendDataToFile()] Could not append data to file.",
00243                             __FILE__, __LINE__);
00244                         fclose($res);
00245                         return false;
00246                     }
00247                     fwrite($res, $this->xmlEnd);
00248                     fclose($res);
00249                 }
00250                 else {
00251                     $this->logger->error("[RemoteCoverageRecorder::appendDataToFile()] Error opening file for writing: " . $filepath,
00252                         __FILE__, __LINE__);
00253                     return false;
00254                 }
00255             }
00256             return true;
00257         }
00258 
00259         /*}}}*/
00260         /*{{{ public function saveCoverageXml() */
00261 
00268         public function saveCoverageXml() {
00269             $filepath = $this->tmpDir . "/" . $this->coverageFileName;
00270             if($this->stopInstrumentation()) {
00271                 $xml = $this->prepareCoverageXml();
00272                 $ret = $this->appendDataToFile($xml);
00273                 if(!$ret) {
00274                     $this->logger->warn("[RemoteCoverageRecorder::saveCoverageXml()] "
00275                     . "ERROR: Nothing was written to " . $filepath,
00276                     __FILE__, __LINE__);
00277                     return false;
00278                 }
00279                 $this->logger->info("[RemoteCoverageRecorder::saveCoverageXml()] "
00280                 . "Saved XML to $filepath; size: [" . filesize($filepath) 
00281                 . "]", __FILE__, __LINE__);
00282                 return true;
00283             }
00284             return false;
00285         }
00286 
00287         /*}}}*/
00288         /*{{{ public function generateReport() */
00289 
00300         public function generateReport($xmlUrl, $stream=false) {
00301             $this->logger->debug("XML Url: " . $xmlUrl, __FILE__, __LINE__);
00302             $this->parseCoverageXml($xmlUrl, true);
00303             $this->logger->debug("Coverage Data final: " . print_r($this->coverageData, true));
00304             parent::generateReport();
00305         }
00306 
00307         /*}}}*/
00308     }
00309 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations