<?php class Fritzing{ public $file; public $files = array(); public $xml,$parts = array(); private $coreIndicator = '/fritzing-parts/'; private $minY,$minX; public $ino ; public $comment ; function __construct($file){ $this->file = $file; $zip = new ZipArchive; $res = $zip->open($this->file); $properties = array(); if ($res !== TRUE) throw new Exception('Impossible d\'ouvrir le ZIP, code:' . $res); for( $i = 0; $i < $zip->numFiles; $i++ ){ $stat = $zip->statIndex($i); if(substr($stat['name'], -3) == '.fz') $this->xml = new SimpleXMLElement($zip->getFromName($stat['name'])); if(substr($stat['name'], -4) == '.ino') $this->ino = $zip->getFromName($stat['name']); $this->files[$stat['name']] = $zip->getFromName($stat['name']); } $zip->close(); $this->parse(); } private function parse(){ $this->minY = 0; $this->minX = 0; foreach($this->xml->instances->instance as $instance){ $part = array(); $part['sigle'] = (string) $instance->title; $attributes = $instance->attributes(); $part['id'] = (string) $attributes->moduleIdRef; $part['properties'] = array(); foreach($instance->property as $property){ $attribute = $property->attributes(); $part['properties'][(string)$attribute['name']] = (string)$attribute['value']; } $part['type'] = 'component'; if(isset($instance->views->breadboardView->geometry)){ $geometry = $instance->views->breadboardView->geometry->attributes(); $part['geometry'] = array( 'x' => array(), 'z' => 0, 'y' => array() ); if(isset($instance->views->breadboardView->geometry->transform)){ $part['geometry']['r'] = $instance->views->breadboardView->geometry->transform; $this->comment = json_encode($instance->views->breadboardView->geometry->transform->attributes()); } if(isset($geometry['wireFlags'])) $part['type'] = 'wire'; foreach ($geometry as $key => $value) { if(substr($key, 0,1) == 'x') $part['geometry']['x'][] =(float)$value; if(substr($key, 0,1) == 'y') $part['geometry']['y'][] =(float)$value; } $part['geometry']['z'] =(float)$geometry['z']; if($this->minY>$part['geometry']['y'][0])$this->minY = $part['geometry']['y'][0]; if($this->minX>$part['geometry']['x'][0])$this->minX = $part['geometry']['x'][0]; if( $part['type']== 'wire'){ $wireAttributes = $instance->views->breadboardView->wireExtras->attributes(); $part['color'] = (string)$wireAttributes['color']; } } $part['component'] = $this->getComponent($attributes->path); $this->parts[] = $part; } $this->minY = abs($this->minY); $this->minX = abs($this->minX); $this->comment = '<h1>Composants</h1><ul>'; foreach ($this->parts as $part) { if($part['type'] == 'component' && isset($part['component']['name'])){ $this->comment .= '<li>'.$part['sigle'].' : '. $part['component']['name'].' ('. $part['component']['description'].')</li>'; } } $this->comment .= '</ul>'; } public function toHtml(){ $html = '<svg id="vis" width="1500" height="500" ></svg> <script> var vis = d3.select("#vis");'; foreach ($this->parts as $part) { if(!isset($part['component']) || $part['type']!='component' || !isset($part['component']['breadboard'])) continue; $html .= "var part = vis.append('svg');"; $html .= "part.attr('x',".($part['geometry']['x'][0]+$this->minX).");"; $html .= "part.attr('y',".($part['geometry']['y'][0]+$this->minY).");"; $html .= "part.html('".str_replace(array("'","\n"),array("\'"," "),$part['component']['breadboard'])."');"; //part.select('g').attr("transform","rotate(45)"); } foreach ($this->parts as $part) { if( $part['type']!='wire' ) continue; $html .= 'var line = vis.append("polyline")'."\n\t\t".'.attr("stroke-linejoin","round").style("stroke", \''.$part['color'].'\').attr("stroke-width", 5)'."\n\t\t"; $x = 0; $y = 0; $html .= '.attr("points","'; for ($i=0;$i<count($part['geometry']['x']);$i++) { $x += $part['geometry']['x'][$i]; $y += $part['geometry']['y'][$i]; if($i==0) $y+= $this->minY; if($i==0) $x+= $this->minX; $html .= "$x,$y,"; } $html .= '");'; } $html .= '</script>'; return $html; } private function getComponent($path){ $component = array(); if(substr($path, 0,1)==':') return $component; if(isset($this->files['part.'.$path])){ $path = 'part.'.basename($path); //if(!isset($this->files[$path])) return; $xmlPart = new SimpleXMLElement($this->files[$path]); $from = ''; }else if(strpos($path,$this->coreIndicator)){ $path = __DIR__.SLASH.substr($path, strpos($path, $this->coreIndicator)+1); if(!file_exists($path)) return $component ; $xmlPart = new SimpleXMLElement(file_get_contents($path)); $from = __DIR__.SLASH.'fritzing-parts/svg/core/'; }else if( file_exists( __DIR__.SLASH.'fritzing-parts/core/'.basename($path))){ $path = __DIR__.SLASH.'fritzing-parts/core/'.basename($path); $xmlPart = new SimpleXMLElement(file_get_contents($path)); $from = __DIR__.SLASH.'fritzing-parts/svg/core/'; }else{ return $component ; } $component['name'] = (string)$xmlPart->title; $component['description'] = (string)$xmlPart->description; $partAttributes = $xmlPart->views->breadboardView->layers->attributes(); if($from==''){ $component['breadboard'] = $this->files['svg.'.str_replace('/', '.', $partAttributes['image'])]; }else{ $component['breadboard'] = file_get_contents($from.$partAttributes['image']); } return $component; } } ?>