Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
genStubFamilyClass.php
Go to the documentation of this file.
1 #!/usr/bin/env php
2 <?php
3 
4 class Ods2Csv
5 {
6 
7 
8  const ALTSEPCHAR = ' --- ';
9  const SEPCHAR = ';';
10 
11  /**
12  * Take an ODS file and produce one CSV
13  *
14  * @param string $odsfile path to ODS file
15  * @param string $csvfile path to CSV output file
16  * @throws Exception
17  * @return void
18  */
19  public function convertOds2csv($odsfile, $csvfile)
20  {
21  if ($odsfile === "" or !file_exists($odsfile) or $csvfile === "") {
22  throw new Exception("ODS convert needs an ODS path and a CSV path");
23  }
24 
25  $content = $this->ods2content($odsfile);
26  $csv = $this->xmlcontent2csv($content);
27  $isWrited = file_put_contents($csvfile, $csv);
28  if ($isWrited === false) {
29  throw new Exception(sprintf("Unable to convert ODS to CSV fo %s", $odsfile));
30  }
31  }
32 
33  /**
34  * Extract content from an ods file
35  *
36  * @param string $odsfile file path
37  * @throws Exception
38  * @return string
39  */
41  {
42  if (!file_exists($odsfile)) {
43  throw new Exception("file $odsfile not found");
44  }
45  $cibledir = uniqid("/var/tmp/ods");
46 
47  $cmd = sprintf("unzip -j %s content.xml -d %s >/dev/null", $odsfile, $cibledir);
48  system($cmd);
49 
50  $contentxml = $cibledir . "/content.xml";
51  if (file_exists($contentxml)) {
52  $content = file_get_contents($contentxml);
53  unlink($contentxml);
54  } else {
55  throw new Exception("unable to extract $odsfile");
56  }
57 
58  rmdir($cibledir);
59  return $content;
60  }
61 
62  /**
63  * @param $xmlcontent
64  *
65  * @throws Exception
66  * @return string
67  */
68  function xmlcontent2csv($xmlcontent)
69  {
70  global $rows;
71  $xml_parser = xml_parser_create();
72  // Use case handling $map_array
73  xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
74  xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 0);
75  xml_set_element_handler($xml_parser, array($this, "startElement"), array($this, "endElement"));
76  xml_set_character_data_handler($xml_parser, array($this, "characterData"));
77 
78  if (!xml_parse($xml_parser, $xmlcontent)) {
79  throw new Exception(sprintf("Unable to parse XML : %s line %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)));
80  }
81  $fcsv = "";
82  xml_parser_free($xml_parser);
83  foreach ($rows as $row) {
84  $fcsv .= implode(self::SEPCHAR, $row) . "\n";
85  }
86  return $fcsv;
87  }
88 
89  /* Handling method for XML parser*/
90  public static function startElement(
91  /** @noinspection PhpUnusedParameterInspection */
92  $parser, $name, $attrs)
93  {
94  global $rows, $nrow, $inrow, $incell, $ncol, $colrepeat, $celldata;
95  if ($name == "TABLE:TABLE-ROW") {
96  $inrow = true;
97  if (isset($rows[$nrow])) {
98  // fill empty cells
99  $idx = 0;
100  foreach ($rows[$nrow] as $k => $v) {
101  if (!isset($rows[$nrow][$idx])) {
102  $rows[$nrow][$idx] = '';
103  }
104  $idx++;
105  }
106  ksort($rows[$nrow], SORT_NUMERIC);
107  }
108  $nrow++;
109  $ncol = 0;
110  $rows[$nrow] = array();
111  }
112 
113  if ($name == "TABLE:TABLE-CELL") {
114  $incell = true;
115  $celldata = "";
116  if (!empty($attrs["TABLE:NUMBER-COLUMNS-REPEATED"])) {
117  $colrepeat = intval($attrs["TABLE:NUMBER-COLUMNS-REPEATED"]);
118  }
119  }
120  if ($name == "TEXT:P") {
121  if (isset($rows[$nrow][$ncol])) {
122  if (strlen($rows[$nrow][$ncol]) > 0) {
123  $rows[$nrow][$ncol] .= '\n';
124  }
125  }
126  }
127  }
128 
129  public static function endElement(
130  /** @noinspection PhpUnusedParameterInspection */
131  $parser, $name)
132  {
133  global $rows, $nrow, $inrow, $incell, $ncol, $colrepeat, $celldata;
134  if ($name == "TABLE:TABLE-ROW") {
135  // Remove trailing empty cells
136  $i = $ncol - 1;
137  while ($i >= 0) {
138  if (strlen($rows[$nrow][$i]) > 0) {
139  break;
140  }
141  $i--;
142  }
143  array_splice($rows[$nrow], $i + 1);
144  $inrow = false;
145  }
146 
147  if ($name == "TABLE:TABLE-CELL") {
148  $incell = false;
149 
150  $rows[$nrow][$ncol] = $celldata;
151 
152  if ($colrepeat > 1) {
153  $rval = $rows[$nrow][$ncol];
154  for ($i = 1; $i < $colrepeat; $i++) {
155  $ncol++;
156  $rows[$nrow][$ncol] = $rval;
157  }
158  }
159  $ncol++;
160  $colrepeat = 0;
161  }
162  }
163 
164  public static function characterData(
165  /** @noinspection PhpUnusedParameterInspection */
166  $parser, $data)
167  {
168  global $inrow, $incell, $celldata;
169  if ($inrow && $incell) {
170  $celldata .= preg_replace('/^\s*[\r\n]\s*$/ms', '', str_replace(self::SEPCHAR, self::ALTSEPCHAR, $data));
171  }
172  }
173 
174  public function seemsODS($filename)
175  {
176  if (preg_match('/\.ods$/', $filename)) return true;
177  $sys = trim(shell_exec(sprintf("file -bi %s", escapeshellarg($filename))));
178  if ($sys == "application/x-zip") return true;
179  if ($sys == "application/vnd.oasis.opendocument.spreadsheet") return true;
180  return false;
181  }
182 }
183 
185 {
186 
187  protected $files = array();
188 
189  public $content = array();
190  public $attr = array();
191 
192  public function addFileToExamine($file)
193  {
194  $this->files[] = $file;
195  }
196 
197 
198  public function getSignifiantContent($file)
199  {
200  $convert = new Ods2Csv();
201  if ($convert->seemsODS($file)) {
202  $csvFile = tempnam("/tmp", "FOO");
203  $convert->convertOds2csv($file, $csvFile);
204  $needUnlink = $csvFile;
205 
206  } else {
207  $csvFile = $file;
208  $needUnlink = false;
209 
210 
211  }
212  $famName = $className = $fromName = $famId = $famTitle = $name='';
213  if (($handle = fopen($csvFile, "r")) !== FALSE) {
214  while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
215  switch ($data[0]) {
216  case "BEGIN":
217  if (isset($data[5])) {
218  $famName = strtolower($data[5]);
219  if (isset($this->content[$famName])) {
220 
221  $className
222  = $this->content[$famName]["className"];
223  $fromName
224  = $this->content[$famName]["fromName"];
225  $famId = $this->content[$famName]["id"];
226  $name = $this->content[$famName]["name"];
227 
228  if (!empty($data[4]) && $data[4] != '-') {
229  $className = $data[4];
230  }
231  if (!empty($data[1]) && $data[1] != '-') {
232  $fromName = ($data[1] == '--') ? ''
233  : $data[1];
234  }
235  if (!empty($data[3]) && $data[3] != '-') {
236  $famId = $data[3];
237  }
238  if (!empty($data[2]) && $data[2] != '-') {
239  $famTitle = $data[2];
240  }
241  } else {
242 
243  $className = $data[4];
244  $fromName = ($data[1] == '--') ? '' : $data[1];
245  $famId = $data[3];
246  $famTitle = $data[2];
247  $name = $data[5];
248  }
249  if (!isset($this->attr[$famName])) {
250  $this->attr[$famName] = array();
251  }
252  }
253  break;
254  case 'CLASS';
255  $className = $data[1];
256  break;
257  case 'PARAM':
258  case 'ATTR':
259  $attrid = strtolower($data[1]);
260  $this->attr[$famName][$attrid] = array(
261  "id" => $attrid,
262  "type" => $data[6],
263  "label" => $data[3],
264  "famName" => $famName);
265  break;
266  case 'END';
267  $this->content[$famName] = array(
268  "famName" => $famName,
269  "name" => $name,
270  "className" => $className,
271  "id" => $famId,
272  "title" => $famTitle,
273  "fromName" => $fromName);
274  break;
275  }
276 
277  }
278  }
279  fclose($handle);
280  if ($needUnlink) {
281  unlink($needUnlink);
282  }
283  $this->completeContent();
284  }
285 
286  protected function completeContent()
287  {
288  foreach ($this->content as $k => $info) {
289  $fromName = $info["fromName"];
290  if ($fromName and is_numeric($fromName)) {
291  foreach ($this->content as $famName => $info2) {
292  if ($info2["id"] == $fromName) {
293  $this->content[$k]["fromName"] = $famName;
294  }
295  }
296  }
297  }
298  }
299 
300  public function generateStubFile()
301  {
302  $phpContent = "<?php\n";
303  $phpContent .= "namespace Dcp\\Family {\n";
304  foreach ($this->content as $famId => $famInfo) {
305  $phpContent .= "\t" . $this->getPhpPart($famInfo) . "\n";
306  }
307  $phpContent .= "}\n";
308  return $phpContent;
309  }
310 
311  protected function getPhpPart(array $info)
312  {
313  $famName = sprintf('%s', ucfirst(strtolower($info["famName"])));
314  if ($info["className"]) {
315  $parentClass = '\\' . $info["className"];
316  } elseif ($info["fromName"]) {
317  $parentClass = sprintf('%s', ucfirst(strtolower($info["fromName"])));
318  } else {
319  $parentClass = 'Document';
320  }
321  $comment = sprintf('/** %s */', $info["title"]);
322  $template = sprintf('class %s extends %s { const familyName="%s";}', $famName, $parentClass, $info["name"]);
323  return $comment . "\n\t" . $template;
324 
325  }
326 
327  public function generateStubAttrFile()
328  {
329 
330  $phpContent = "namespace Dcp\\AttributeIdentifiers {\n";
331  foreach ($this->attr as $famName => $attrInfo) {
332  $phpContent .= "\t" . $this->getPhpAttrPart($famName, $attrInfo) . "\n";
333  }
334  $phpContent .= "}\n";
335  return $phpContent;
336  }
337 
338  protected function getPhpAttrPart($famName, array $info)
339  {
340  $famInfo = $this->content[$famName];
341  if ($famInfo["fromName"]) {
342  $parentClass = sprintf('%s', ucfirst(strtolower($famInfo["fromName"])));
343  } else {
344  $parentClass = '';
345  }
346  $comment = sprintf('/** %s */', $famInfo["title"]);
347  if ($parentClass) {
348  $template = sprintf("class %s extends %s {\n", ucwords($famName), $parentClass);
349  } else {
350  $template = sprintf("class %s {\n", ucwords($famName));
351 
352  }
353  foreach ($info as $attrid => $attrInfo) {
354  $template .= sprintf("\t\t/** [%s] %s */\n", str_replace('*',' ', $attrInfo["type"]),str_replace('*', ' ',$attrInfo["label"]));
355  $template .= sprintf("\t\tconst %s='%s';\n", $attrInfo["id"], $attrInfo["id"]);
356  }
357  $template .= "\t}";
358  return $comment . "\n\t" . $template;
359  }
360 }
361 
362 $s = new GenerateStub();
363 foreach ($argv as $k => $aFile) {
364  if ($k > 0) {
365  $s->getSignifiantContent($aFile);
366  }
367 }
368 print($s->generateStubFile());
369 print($s->generateStubAttrFile());
$csv
Definition: checkVault.php:41
static startElement($parser, $name, $attrs)
seemsODS($filename)
$comment
Definition: fdl_execute.php:35
convertOds2csv($odsfile, $csvfile)
$filename
$nrow
Definition: Api/ods2csv.php:21
$file
static endElement($parser, $name)
const SEPCHAR
Definition: import_file.php:26
ods2content($odsfile)
const ALTSEPCHAR
Definition: import_file.php:25
$csvfile
const ALTSEPCHAR
foreach($argv as $arg) $cmd
getPhpPart(array $info)
getPhpAttrPart($famName, array $info)
print
Definition: checklist.php:49
$odsfile
$className
static characterData($parser, $data)
$info
Definition: geticon.php:30
xmlcontent2csv($xmlcontent)
$data
← centre documentaire © anakeen