/** * Redefinition of TBS method to add parameter 'cell' to set value with native OpenDocument format in spreadsheet * * refactoring code from egroupware/perp_api/inc/report/ooo.inc.php * * @param string $Txt TBS source * @param string $Loc TBS locator * @param string $Value TBS data to merge * @param string $CheckSub TBS checksub ??? */ public function meth_Locator_Replace(&$Txt, &$Loc, &$Value, $CheckSub) { if (!isset($Loc->PrmLst['type']) && !isset($Loc->PrmLst['image']) && !isset($Loc->PrmLst['link'])) { return parent::meth_Locator_Replace($Txt, $Loc, $Value, $CheckSub); } // keep 'Loc' position for the end $posBeg = $Loc->PosBeg; $posEnd = $Loc->PosEnd; // get data $data = isset($Value) ? $Value : null; foreach ($Loc->SubLst as $sub) { $data = isset($Value[$sub]) ? $Value[$sub] : null; } // ----- parameter = type if (isset($Loc->PrmLst['type'])) { if ($data == '') { $Txt = substr_replace($Txt, '', $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); $Loc->PosBeg = $posBeg; $Loc->PosEnd = $posEnd; return $Loc->PosBeg; } // get container enlarged to table:table-cell $Loc->Enlarged = $this->f_Loc_EnlargeToStr($Txt, $Loc, '<table:table-cell', '/table:table-cell>'); $container = substr($Txt, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); if ($container == '') { throw new tinyDocException(sprintf('<table:table-cell not found in document "%s"', $this->getXmlFilename())); } // OpenOffice attributes cell - see : http://books.evc-cit.info/odbook/ch05.html#table-cells-section switch ($Loc->PrmLst['type']) { case 'datetime': case 'date': case 'dt': case 'd': $attribute = sprintf('office:value-type="date" office:date-value="%s"', str_replace(' ', 'T', $data)); break; case 'time': case 't': list($h, $m, $s) = split(":", $data); $attribute = sprintf('office:value-type="time" office:time-value="PT%sH%sM%sS"', $h, $m, $s); break; case 'percentage': case 'percent': case 'p': $attribute = sprintf('office:value-type="percentage" office:value="%s"', $data); break; case 'currency': case 'cur': case 'c': //$attribute = sprintf('office:value-type="currency" office:currency="EUR" office:value="%s"', $data); // still not necessary to fix the currency $attribute = sprintf('office:value-type="currency" office:value="%s"', $data); break; case 'number': case 'n': case 'float': case 'f': $attribute = sprintf('office:value-type="float" office:value="%s"', $data); break; case 'int': case 'i': $attribute = sprintf('office:value-type="float" office:value="%d"', $data); break; default: case 'string': case 's': $attribute = sprintf('office:value-type="string"'); break; } // new container $newContainer = preg_replace('/office:value-type="string"/', $attribute, $container); // replace the new cell containter in the main Txt $Txt = substr_replace($Txt, $newContainer, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); // correct 'Loc' to include the change of the new cell container $delta = strlen($newContainer) - strlen($container); $Loc->PosBeg = $posBeg + $delta; $Loc->PosEnd = $posEnd + $delta; $Loc->Enlarged = null; } // ----- parameter = image if (isset($Loc->PrmLst['image'])) { // get container enlarged to draw:frame $Loc->Enlarged = $this->f_Loc_EnlargeToStr($Txt, $Loc, '<draw:frame', '/draw:frame>'); $container = substr($Txt, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); if ($container == '') { throw new tinyDocException(sprintf('<draw:frame not found in document "%s"', $this->getXmlFilename())); } // test if data is empty or if file not exists if ($data == '' || !file_exists($data)) { $Txt = substr_replace($Txt, '', $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); $Loc->PosBeg = $posBeg; $Loc->PosEnd = $posEnd; $Loc->Enlarged = null; return $Loc->PosBeg; } $picture = 'Pictures/' . basename($data); // image size $size = @getimagesize($data); if ($size === false) { throw new tinyDocException(sprintf('Invalid image format "%"', $data)); } else { list($width, $height) = $size; } // image ratio $ratio = 1; switch (strtolower($Loc->PrmLst['image'])) { case 'fit': if (preg_match('/svg:width="(.*?)(cm|in|mm|px)" svg:height="(.*?)(cm|in|mm|px)"/', $container, $matches)) { $ratio_w = self::convertToCm($matches[1], $matches[2]) / self::convertToCm($width, 'px'); $ratio_h = self::convertToCm($matches[3], $matches[4]) / self::convertToCm($height, 'px'); $ratio = min($ratio_w, $ratio_h); } break; case 'max': if (preg_match('/svg:width="(.*?)(cm|in|mm|px)" svg:height="(.*?)(cm|in|mm|px)"/', $container, $matches)) { $ratio_w = self::convertToCm($matches[1], $matches[2]) / self::convertToCm($width, 'px'); $ratio_h = self::convertToCm($matches[3], $matches[4]) / self::convertToCm($height, 'px'); $ratio = min(1, $ratio_w, $ratio_h); } break; default: if (preg_match('/([0-9\\.]*)%/', $Loc->PrmLst['image'], $matches) > 0) { $ratio = $matches[1] / 100; } break; } // replace values $newContainer = $container; $newContainer = preg_replace('/svg:width="(.*?)"/', sprintf('svg:width="%scm"', self::convertToCm($width, 'px') * $ratio), $newContainer); $newContainer = preg_replace('/svg:height="(.*?)"/', sprintf('svg:height="%scm"', self::convertToCm($height, 'px') * $ratio), $newContainer); $newContainer = preg_replace('/xlink:href="(.*?)"/', sprintf('xlink:href="%s"', $picture), $newContainer); // add file $this->addFile($data, $picture); // replace the new cell containter in the main Txt $Txt = substr_replace($Txt, $newContainer, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); $Loc->PosBeg = $posBeg; $Loc->PosEnd = $posEnd; $Loc->Enlarged = null; } // ----- parameter = link if (isset($Loc->PrmLst['link'])) { if ($data == '') { $Txt = substr_replace($Txt, '', $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); $Loc->PosBeg = $posBeg; $Loc->PosEnd = $posEnd; return $Loc->PosBeg; } $container = substr($Txt, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); $title = $Loc->PrmLst['link'] != '1' ? $Loc->PrmLst['link'] : $data; $newContainer = sprintf('<text:a xlink:type="simple" xlink:href="%s">%s</text:a>', $data, $title); $Txt = substr_replace($Txt, $newContainer, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); // before return, restore 'Loc' with beginning values (to work with block) $Loc->PosBeg = $posBeg; $Loc->PosEnd = $posEnd; return $Loc->PosEnd; } // call the parent method to insert the value $ret = parent::meth_Locator_Replace($Txt, $Loc, $Value, $CheckSub); // before return, restore 'Loc' with beginning values (to work with block) $Loc->PosBeg = $posBeg; $Loc->PosEnd = $posEnd; return $ret; }
/** * Redefinition of TBS method to add parameter 'cell' to set value with native OpenDocument format in spreadsheet * * refactoring code from egroupware/perp_api/inc/report/ooo.inc.php * * @param string $Txt TBS source * @param string $Loc TBS locator * @param string $Value TBS data to merge * @param string $CheckSub TBS checksub ??? */ public function meth_Locator_Replace(&$Txt, &$Loc, &$Value, $CheckSub) { if (!isset($Loc->PrmLst['type'])) { return parent::meth_Locator_Replace($Txt, $Loc, $Value, $CheckSub); } // keep 'Loc' for the end $posBeg = $Loc->PosBeg; $posEnd = $Loc->PosEnd; // get data $data = $Value[$Loc->SubLst[0]]; // new cell attribute // see : http://books.evc-cit.info/odbook/ch05.html#table-cells-section switch ($Loc->PrmLst['type']) { case 'datetime': case 'date': case 'dt': case 'd': $cellAttribute = sprintf('office:value-type="date" office:date-value="%s"', str_replace(' ', 'T', $data)); break; case 'time': case 't': list($h, $m, $s) = split(":", $data); $cellAttribute = sprintf('office:value-type="time" office:time-value="PT%sH%sM%sS"', $h, $m, $s); break; case 'percentage': case 'percent': case 'p': $cellAttribute = sprintf('office:value-type="percentage" office:value="%s"', $data); break; case 'currency': case 'cur': case 'c': //$cellAttribute = sprintf('office:value-type="currency" office:currency="EUR" office:value="%s"', $data); // still not necessary to fix the currency $cellAttribute = sprintf('office:value-type="currency" office:value="%s"', $data); break; case 'float': case 'f': $cellAttribute = sprintf('office:value-type="float" office:value="%s"', $data); break; case 'int': case 'i': $cellAttribute = sprintf('office:value-type="float" office:value="%d"', $data); break; case 'boolean': case 'bool': case 'b': $cellAttribute = sprintf('office:value-type="float" office:value="%d"', $data); break; default: case 'string': case 's': $cellAttribute = sprintf('office:value-type="string"'); break; } // get cell container enlarged to table:table-cell $Loc->Enlarged = $this->f_Loc_EnlargeToStr($Txt, $Loc, '<table:table-cell', '>'); $cellContainer = substr($Txt, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); // new cell container $newCellContainer = preg_replace('/office:value-type="string"/', $cellAttribute, $cellContainer); // replace the new cell containter in the main Txt $Txt = substr_replace($Txt, $newCellContainer, $Loc->PosBeg, $Loc->PosEnd - $Loc->PosBeg + 1); // correct 'Loc' to include the change of the new cell container $delta = strlen($newCellContainer) - strlen($cellContainer); $Loc->PosBeg = $posBeg + $delta; $Loc->PosEnd = $posEnd + $delta; $Loc->Enlarged = null; // call the parent method to insert the value $ret = parent::meth_Locator_Replace($Txt, $Loc, $Value, $CheckSub); // before return, restore 'Loc' with beginning values (to work with block) $Loc->PosBeg = $posBeg; $Loc->PosEnd = $posEnd; return $ret; }