Fritzing.class.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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 $comment ;
  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->comment = 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. $this->comment = '<h1>Composants</h1><ul>';
  70. foreach ($this->parts as $part) {
  71. if($part['type'] == 'component' && isset($part['component']['name'])){
  72. $this->comment .= '<li>'.$part['sigle'].' : '. $part['component']['name'].' ('. $part['component']['description'].')</li>';
  73. }
  74. }
  75. $this->comment .= '</ul>';
  76. }
  77. public function toHtml(){
  78. $html = '<svg id="vis" width="1500" height="500" ></svg>
  79. <script>
  80. var vis = d3.select("#vis");';
  81. foreach ($this->parts as $part) {
  82. if(!isset($part['component']) || $part['type']!='component' || !isset($part['component']['breadboard'])) continue;
  83. $html .= "var part = vis.append('svg');";
  84. $html .= "part.attr('x',".($part['geometry']['x'][0]+$this->minX).");";
  85. $html .= "part.attr('y',".($part['geometry']['y'][0]+$this->minY).");";
  86. $html .= "part.html('".str_replace(array("'","\n"),array("\'"," "),$part['component']['breadboard'])."');";
  87. //part.select('g').attr("transform","rotate(45)");
  88. }
  89. foreach ($this->parts as $part) {
  90. if( $part['type']!='wire' ) continue;
  91. $html .= 'var line = vis.append("polyline")'."\n\t\t".'.attr("stroke-linejoin","round").style("stroke", \''.$part['color'].'\').attr("stroke-width", 5)'."\n\t\t";
  92. $x = 0;
  93. $y = 0;
  94. $html .= '.attr("points","';
  95. for ($i=0;$i<count($part['geometry']['x']);$i++) {
  96. $x += $part['geometry']['x'][$i];
  97. $y += $part['geometry']['y'][$i];
  98. if($i==0) $y+= $this->minY;
  99. if($i==0) $x+= $this->minX;
  100. $html .= "$x,$y,";
  101. }
  102. $html .= '");';
  103. }
  104. $html .= '</script>';
  105. return $html;
  106. }
  107. private function getComponent($path){
  108. $component = array();
  109. if(substr($path, 0,1)==':') return $component;
  110. if(isset($this->files['part.'.$path])){
  111. $path = 'part.'.basename($path);
  112. //if(!isset($this->files[$path])) return;
  113. $xmlPart = new SimpleXMLElement($this->files[$path]);
  114. $from = '';
  115. }else if(strpos($path,$this->coreIndicator)){
  116. $path = __DIR__.SLASH.substr($path, strpos($path, $this->coreIndicator)+1);
  117. if(!file_exists($path)) return $component ;
  118. $xmlPart = new SimpleXMLElement(file_get_contents($path));
  119. $from = __DIR__.SLASH.'fritzing-parts/svg/core/';
  120. }else if( file_exists( __DIR__.SLASH.'fritzing-parts/core/'.basename($path))){
  121. $path = __DIR__.SLASH.'fritzing-parts/core/'.basename($path);
  122. $xmlPart = new SimpleXMLElement(file_get_contents($path));
  123. $from = __DIR__.SLASH.'fritzing-parts/svg/core/';
  124. }else{
  125. return $component ;
  126. }
  127. $component['name'] = (string)$xmlPart->title;
  128. $component['description'] = (string)$xmlPart->description;
  129. $partAttributes = $xmlPart->views->breadboardView->layers->attributes();
  130. if($from==''){
  131. $component['breadboard'] = $this->files['svg.'.str_replace('/', '.', $partAttributes['image'])];
  132. }else{
  133. $component['breadboard'] = file_get_contents($from.$partAttributes['image']);
  134. }
  135. return $component;
  136. }
  137. }
  138. ?>