Fritzing.class.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. class Fritzing{
  3. public $file;
  4. public $files = array();
  5. public $xml,$parts = array();
  6. private $coreIndicator = '/fritzing-parts/';
  7. private $minY,$minX;
  8. public $ino ;
  9. public $debug ;
  10. function __construct($file){
  11. $this->file = $file;
  12. $zip = new ZipArchive;
  13. $res = $zip->open($this->file);
  14. $properties = array();
  15. if ($res !== TRUE) throw new Exception('Impossible d\'ouvrir le ZIP, code:' . $res);
  16. for( $i = 0; $i < $zip->numFiles; $i++ ){
  17. $stat = $zip->statIndex($i);
  18. if(substr($stat['name'], -3) == '.fz') $this->xml = new SimpleXMLElement($zip->getFromName($stat['name']));
  19. if(substr($stat['name'], -4) == '.ino') $this->ino = $zip->getFromName($stat['name']);
  20. $this->files[$stat['name']] = $zip->getFromName($stat['name']);
  21. }
  22. $zip->close();
  23. $this->parse();
  24. }
  25. private function parse(){
  26. $this->minY = 0;
  27. $this->minX = 0;
  28. foreach($this->xml->instances->instance as $instance){
  29. $part = array();
  30. $part['sigle'] = (string) $instance->title;
  31. $attributes = $instance->attributes();
  32. $part['id'] = (string) $attributes->moduleIdRef;
  33. $part['properties'] = array();
  34. foreach($instance->property as $property){
  35. $attribute = $property->attributes();
  36. $part['properties'][(string)$attribute['name']] = (string)$attribute['value'];
  37. }
  38. $part['type'] = 'component';
  39. if(isset($instance->views->breadboardView->geometry)){
  40. $geometry = $instance->views->breadboardView->geometry->attributes();
  41. $part['geometry'] = array(
  42. 'x' => array(),
  43. 'z' => 0,
  44. 'y' => array()
  45. );
  46. if(isset($instance->views->breadboardView->geometry->transform)){
  47. $part['geometry']['r'] = $instance->views->breadboardView->geometry->transform;
  48. $this->debug = json_encode($instance->views->breadboardView->geometry->transform->attributes());
  49. }
  50. if(isset($geometry['wireFlags']))
  51. $part['type'] = 'wire';
  52. foreach ($geometry as $key => $value) {
  53. if(substr($key, 0,1) == 'x') $part['geometry']['x'][] =(float)$value;
  54. if(substr($key, 0,1) == 'y') $part['geometry']['y'][] =(float)$value;
  55. }
  56. $part['geometry']['z'] =(float)$geometry['z'];
  57. if($this->minY>$part['geometry']['y'][0])$this->minY = $part['geometry']['y'][0];
  58. if($this->minX>$part['geometry']['x'][0])$this->minX = $part['geometry']['x'][0];
  59. if( $part['type']== 'wire'){
  60. $wireAttributes = $instance->views->breadboardView->wireExtras->attributes();
  61. $part['color'] = (string)$wireAttributes['color'];
  62. }
  63. }
  64. $part['component'] = $this->getComponent($attributes->path);
  65. $this->parts[] = $part;
  66. }
  67. $this->minY = abs($this->minY);
  68. $this->minX = abs($this->minX);
  69. }
  70. public function toHtml(){
  71. $html = '<svg id="vis" width="1500" height="500" ></svg>
  72. <script>
  73. var vis = d3.select("#vis");';
  74. foreach ($this->parts as $part) {
  75. if(!isset($part['component']) || $part['type']!='component' || !isset($part['component']['breadboard'])) continue;
  76. $html .= "var part = vis.append('svg');";
  77. $html .= "part.attr('x',".($part['geometry']['x'][0]+$this->minX).");";
  78. $html .= "part.attr('y',".($part['geometry']['y'][0]+$this->minY).");";
  79. $html .= "part.html('".str_replace(array("'","\n"),array("\'"," "),$part['component']['breadboard'])."');";
  80. if(isset($part['geometry']['r']))
  81. $html .= "part.select('g').attr('transform','matrix(".$part['geometry']['r']['m11']." ".$part['geometry']['r']['m12']." ".$part['geometry']['r']['m21']." ".$part['geometry']['r']['m22']." ".$part['geometry']['r']['m31']." ".$part['geometry']['r']['m32'].")');";
  82. }
  83. foreach ($this->parts as $part) {
  84. if( $part['type']!='wire' ) continue;
  85. $html .= 'var line = vis.append("polyline")'."\n\t\t".'.attr("stroke-linejoin","round").style("stroke", \''.$part['color'].'\').attr("stroke-width", 5)'."\n\t\t";
  86. $x = 0;
  87. $y = 0;
  88. $html .= '.attr("points","';
  89. $points = array();
  90. for ($i=0;$i<count($part['geometry']['x']);$i++) {
  91. $x += $part['geometry']['x'][$i];
  92. $y += $part['geometry']['y'][$i];
  93. if($i==0) $y+= $this->minY;
  94. if($i==0) $x+= $this->minX;
  95. //$html .= "$x,$y,";
  96. $points[] = $x;
  97. $points[] = $y;
  98. }
  99. $html .= implode(',', $points);
  100. $html .= '");';
  101. }
  102. $html .= '</script>';
  103. return $html;
  104. }
  105. private function getComponent($path){
  106. $component = array();
  107. if(substr($path, 0,1)==':') return $component;
  108. if(isset($this->files['part.'.$path])){
  109. $path = 'part.'.basename($path);
  110. //if(!isset($this->files[$path])) return;
  111. $xmlPart = new SimpleXMLElement($this->files[$path]);
  112. $from = '';
  113. }else if(strpos($path,$this->coreIndicator)){
  114. $path = __DIR__.SLASH.substr($path, strpos($path, $this->coreIndicator)+1);
  115. if(!file_exists($path)) return $component ;
  116. $xmlPart = new SimpleXMLElement(file_get_contents($path));
  117. $from = __DIR__.SLASH.'fritzing-parts/svg/core/';
  118. }else if( file_exists( __DIR__.SLASH.'fritzing-parts/core/'.basename($path))){
  119. $path = __DIR__.SLASH.'fritzing-parts/core/'.basename($path);
  120. $xmlPart = new SimpleXMLElement(file_get_contents($path));
  121. $from = __DIR__.SLASH.'fritzing-parts/svg/core/';
  122. }else{
  123. return $component ;
  124. }
  125. $component['name'] = (string)$xmlPart->title;
  126. $component['description'] = (string)$xmlPart->description;
  127. $partAttributes = $xmlPart->views->breadboardView->layers->attributes();
  128. if($from==''){
  129. $component['breadboard'] = $this->files['svg.'.str_replace('/', '.', $partAttributes['image'])];
  130. }else{
  131. $component['breadboard'] = file_get_contents($from.$partAttributes['image']);
  132. }
  133. return $component;
  134. }
  135. }
  136. ?>