You've already forked qlg.tsgz.moe
Init Repo
This commit is contained in:
102
extend/phpexcel/PHPExcel/Shared/CodePage.php
Executable file
102
extend/phpexcel/PHPExcel/Shared/CodePage.php
Executable file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_CodePage
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_CodePage
|
||||
{
|
||||
/**
|
||||
* Convert Microsoft Code Page Identifier to Code Page Name which iconv
|
||||
* and mbstring understands
|
||||
*
|
||||
* @param integer $codePage Microsoft Code Page Indentifier
|
||||
* @return string Code Page Name
|
||||
* @throws PHPExcel_Exception
|
||||
*/
|
||||
public static function NumberToName($codePage = 1252)
|
||||
{
|
||||
switch ($codePage) {
|
||||
case 367: return 'ASCII'; break; // ASCII
|
||||
case 437: return 'CP437'; break; // OEM US
|
||||
case 720: throw new PHPExcel_Exception('Code page 720 not supported.');
|
||||
break; // OEM Arabic
|
||||
case 737: return 'CP737'; break; // OEM Greek
|
||||
case 775: return 'CP775'; break; // OEM Baltic
|
||||
case 850: return 'CP850'; break; // OEM Latin I
|
||||
case 852: return 'CP852'; break; // OEM Latin II (Central European)
|
||||
case 855: return 'CP855'; break; // OEM Cyrillic
|
||||
case 857: return 'CP857'; break; // OEM Turkish
|
||||
case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro
|
||||
case 860: return 'CP860'; break; // OEM Portugese
|
||||
case 861: return 'CP861'; break; // OEM Icelandic
|
||||
case 862: return 'CP862'; break; // OEM Hebrew
|
||||
case 863: return 'CP863'; break; // OEM Canadian (French)
|
||||
case 864: return 'CP864'; break; // OEM Arabic
|
||||
case 865: return 'CP865'; break; // OEM Nordic
|
||||
case 866: return 'CP866'; break; // OEM Cyrillic (Russian)
|
||||
case 869: return 'CP869'; break; // OEM Greek (Modern)
|
||||
case 874: return 'CP874'; break; // ANSI Thai
|
||||
case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS
|
||||
case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK
|
||||
case 949: return 'CP949'; break; // ANSI Korean (Wansung)
|
||||
case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5
|
||||
case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8)
|
||||
case 1250: return 'CP1250'; break; // ANSI Latin II (Central European)
|
||||
case 1251: return 'CP1251'; break; // ANSI Cyrillic
|
||||
case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program
|
||||
case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7)
|
||||
case 1253: return 'CP1253'; break; // ANSI Greek
|
||||
case 1254: return 'CP1254'; break; // ANSI Turkish
|
||||
case 1255: return 'CP1255'; break; // ANSI Hebrew
|
||||
case 1256: return 'CP1256'; break; // ANSI Arabic
|
||||
case 1257: return 'CP1257'; break; // ANSI Baltic
|
||||
case 1258: return 'CP1258'; break; // ANSI Vietnamese
|
||||
case 1361: return 'CP1361'; break; // ANSI Korean (Johab)
|
||||
case 10000: return 'MAC'; break; // Apple Roman
|
||||
case 10006: return 'MACGREEK'; break; // Macintosh Greek
|
||||
case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic
|
||||
case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312)
|
||||
case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe
|
||||
case 10079: return 'MACICELAND'; break; // Macintosh Icelandic
|
||||
case 10081: return 'MACTURKISH'; break; // Macintosh Turkish
|
||||
case 32768: return 'MAC'; break; // Apple Roman
|
||||
case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.');
|
||||
break; // ANSI Latin I (BIFF2-BIFF3)
|
||||
case 65000: return 'UTF-7'; break; // Unicode (UTF-7)
|
||||
case 65001: return 'UTF-8'; break; // Unicode (UTF-8)
|
||||
}
|
||||
|
||||
throw new PHPExcel_Exception('Unknown codepage: ' . $codePage);
|
||||
}
|
||||
|
||||
}
|
393
extend/phpexcel/PHPExcel/Shared/Date.php
Executable file
393
extend/phpexcel/PHPExcel/Shared/Date.php
Executable file
@ -0,0 +1,393 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Date
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Date
|
||||
{
|
||||
/** constants */
|
||||
const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0
|
||||
const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0
|
||||
|
||||
/*
|
||||
* Names of the months of the year, indexed by shortname
|
||||
* Planned usage for locale settings
|
||||
*
|
||||
* @public
|
||||
* @var string[]
|
||||
*/
|
||||
public static $_monthNames = array( 'Jan' => 'January',
|
||||
'Feb' => 'February',
|
||||
'Mar' => 'March',
|
||||
'Apr' => 'April',
|
||||
'May' => 'May',
|
||||
'Jun' => 'June',
|
||||
'Jul' => 'July',
|
||||
'Aug' => 'August',
|
||||
'Sep' => 'September',
|
||||
'Oct' => 'October',
|
||||
'Nov' => 'November',
|
||||
'Dec' => 'December',
|
||||
);
|
||||
|
||||
/*
|
||||
* Names of the months of the year, indexed by shortname
|
||||
* Planned usage for locale settings
|
||||
*
|
||||
* @public
|
||||
* @var string[]
|
||||
*/
|
||||
public static $_numberSuffixes = array( 'st',
|
||||
'nd',
|
||||
'rd',
|
||||
'th',
|
||||
);
|
||||
|
||||
/*
|
||||
* Base calendar year to use for calculations
|
||||
*
|
||||
* @private
|
||||
* @var int
|
||||
*/
|
||||
protected static $_excelBaseDate = self::CALENDAR_WINDOWS_1900;
|
||||
|
||||
/**
|
||||
* Set the Excel calendar (Windows 1900 or Mac 1904)
|
||||
*
|
||||
* @param integer $baseDate Excel base date (1900 or 1904)
|
||||
* @return boolean Success or failure
|
||||
*/
|
||||
public static function setExcelCalendar($baseDate) {
|
||||
if (($baseDate == self::CALENDAR_WINDOWS_1900) ||
|
||||
($baseDate == self::CALENDAR_MAC_1904)) {
|
||||
self::$_excelBaseDate = $baseDate;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
} // function setExcelCalendar()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Excel calendar (Windows 1900 or Mac 1904)
|
||||
*
|
||||
* @return integer Excel base date (1900 or 1904)
|
||||
*/
|
||||
public static function getExcelCalendar() {
|
||||
return self::$_excelBaseDate;
|
||||
} // function getExcelCalendar()
|
||||
|
||||
|
||||
/**
|
||||
* Convert a date from Excel to PHP
|
||||
*
|
||||
* @param long $dateValue Excel date/time value
|
||||
* @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as
|
||||
* a UST timestamp, or adjusted to UST
|
||||
* @param string $timezone The timezone for finding the adjustment from UST
|
||||
* @return long PHP serialized date/time
|
||||
*/
|
||||
public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) {
|
||||
if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) {
|
||||
$my_excelBaseDate = 25569;
|
||||
// Adjust for the spurious 29-Feb-1900 (Day 60)
|
||||
if ($dateValue < 60) {
|
||||
--$my_excelBaseDate;
|
||||
}
|
||||
} else {
|
||||
$my_excelBaseDate = 24107;
|
||||
}
|
||||
|
||||
// Perform conversion
|
||||
if ($dateValue >= 1) {
|
||||
$utcDays = $dateValue - $my_excelBaseDate;
|
||||
$returnValue = round($utcDays * 86400);
|
||||
if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) {
|
||||
$returnValue = (integer) $returnValue;
|
||||
}
|
||||
} else {
|
||||
$hours = round($dateValue * 24);
|
||||
$mins = round($dateValue * 1440) - round($hours * 60);
|
||||
$secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60);
|
||||
$returnValue = (integer) gmmktime($hours, $mins, $secs);
|
||||
}
|
||||
|
||||
$timezoneAdjustment = ($adjustToTimezone) ?
|
||||
PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) :
|
||||
0;
|
||||
|
||||
// Return
|
||||
return $returnValue + $timezoneAdjustment;
|
||||
} // function ExcelToPHP()
|
||||
|
||||
|
||||
/**
|
||||
* Convert a date from Excel to a PHP Date/Time object
|
||||
*
|
||||
* @param integer $dateValue Excel date/time value
|
||||
* @return integer PHP date/time object
|
||||
*/
|
||||
public static function ExcelToPHPObject($dateValue = 0) {
|
||||
$dateTime = self::ExcelToPHP($dateValue);
|
||||
$days = floor($dateTime / 86400);
|
||||
$time = round((($dateTime / 86400) - $days) * 86400);
|
||||
$hours = round($time / 3600);
|
||||
$minutes = round($time / 60) - ($hours * 60);
|
||||
$seconds = round($time) - ($hours * 3600) - ($minutes * 60);
|
||||
|
||||
$dateObj = date_create('1-Jan-1970+'.$days.' days');
|
||||
$dateObj->setTime($hours,$minutes,$seconds);
|
||||
|
||||
return $dateObj;
|
||||
} // function ExcelToPHPObject()
|
||||
|
||||
|
||||
/**
|
||||
* Convert a date from PHP to Excel
|
||||
*
|
||||
* @param mixed $dateValue PHP serialized date/time or date object
|
||||
* @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as
|
||||
* a UST timestamp, or adjusted to UST
|
||||
* @param string $timezone The timezone for finding the adjustment from UST
|
||||
* @return mixed Excel date/time value
|
||||
* or boolean FALSE on failure
|
||||
*/
|
||||
public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) {
|
||||
$saveTimeZone = date_default_timezone_get();
|
||||
date_default_timezone_set('UTC');
|
||||
$retValue = FALSE;
|
||||
if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) {
|
||||
$retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'),
|
||||
$dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s')
|
||||
);
|
||||
} elseif (is_numeric($dateValue)) {
|
||||
$retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue),
|
||||
date('H',$dateValue), date('i',$dateValue), date('s',$dateValue)
|
||||
);
|
||||
}
|
||||
date_default_timezone_set($saveTimeZone);
|
||||
|
||||
return $retValue;
|
||||
} // function PHPToExcel()
|
||||
|
||||
|
||||
/**
|
||||
* FormattedPHPToExcel
|
||||
*
|
||||
* @param long $year
|
||||
* @param long $month
|
||||
* @param long $day
|
||||
* @param long $hours
|
||||
* @param long $minutes
|
||||
* @param long $seconds
|
||||
* @return long Excel date/time value
|
||||
*/
|
||||
public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) {
|
||||
if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) {
|
||||
//
|
||||
// Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel
|
||||
// This affects every date following 28th February 1900
|
||||
//
|
||||
$excel1900isLeapYear = TRUE;
|
||||
if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; }
|
||||
$my_excelBaseDate = 2415020;
|
||||
} else {
|
||||
$my_excelBaseDate = 2416481;
|
||||
$excel1900isLeapYear = FALSE;
|
||||
}
|
||||
|
||||
// Julian base date Adjustment
|
||||
if ($month > 2) {
|
||||
$month -= 3;
|
||||
} else {
|
||||
$month += 9;
|
||||
--$year;
|
||||
}
|
||||
|
||||
// Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0)
|
||||
$century = substr($year,0,2);
|
||||
$decade = substr($year,2,2);
|
||||
$excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear;
|
||||
|
||||
$excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400;
|
||||
|
||||
return (float) $excelDate + $excelTime;
|
||||
} // function FormattedPHPToExcel()
|
||||
|
||||
|
||||
/**
|
||||
* Is a given cell a date/time?
|
||||
*
|
||||
* @param PHPExcel_Cell $pCell
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isDateTime(PHPExcel_Cell $pCell) {
|
||||
return self::isDateTimeFormat(
|
||||
$pCell->getWorksheet()->getStyle(
|
||||
$pCell->getCoordinate()
|
||||
)->getNumberFormat()
|
||||
);
|
||||
} // function isDateTime()
|
||||
|
||||
|
||||
/**
|
||||
* Is a given number format a date/time?
|
||||
*
|
||||
* @param PHPExcel_Style_NumberFormat $pFormat
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) {
|
||||
return self::isDateTimeFormatCode($pFormat->getFormatCode());
|
||||
} // function isDateTimeFormat()
|
||||
|
||||
|
||||
private static $possibleDateFormatCharacters = 'eymdHs';
|
||||
|
||||
/**
|
||||
* Is a given number format code a date/time?
|
||||
*
|
||||
* @param string $pFormatCode
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isDateTimeFormatCode($pFormatCode = '') {
|
||||
if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL))
|
||||
// "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check)
|
||||
return FALSE;
|
||||
if (preg_match('/[0#]E[+-]0/i', $pFormatCode))
|
||||
// Scientific format
|
||||
return FALSE;
|
||||
// Switch on formatcode
|
||||
switch ($pFormatCode) {
|
||||
// Explicitly defined date formats
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17:
|
||||
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Typically number, currency or accounting (or occasionally fraction) formats
|
||||
if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) {
|
||||
return FALSE;
|
||||
}
|
||||
// Try checking for any of the date formatting characters that don't appear within square braces
|
||||
if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) {
|
||||
// We might also have a format mask containing quoted strings...
|
||||
// we don't want to test for any of our characters within the quoted blocks
|
||||
if (strpos($pFormatCode,'"') !== FALSE) {
|
||||
$segMatcher = FALSE;
|
||||
foreach(explode('"',$pFormatCode) as $subVal) {
|
||||
// Only test in alternate array entries (the non-quoted blocks)
|
||||
if (($segMatcher = !$segMatcher) &&
|
||||
(preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// No date...
|
||||
return FALSE;
|
||||
} // function isDateTimeFormatCode()
|
||||
|
||||
|
||||
/**
|
||||
* Convert a date/time string to Excel time
|
||||
*
|
||||
* @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10'
|
||||
* @return float|FALSE Excel date/time serial value
|
||||
*/
|
||||
public static function stringToExcel($dateValue = '') {
|
||||
if (strlen($dateValue) < 2)
|
||||
return FALSE;
|
||||
if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue))
|
||||
return FALSE;
|
||||
|
||||
$dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue);
|
||||
|
||||
if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) {
|
||||
return FALSE;
|
||||
} else {
|
||||
if (strpos($dateValue, ':') !== FALSE) {
|
||||
$timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue);
|
||||
if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) {
|
||||
return FALSE;
|
||||
}
|
||||
$dateValueNew += $timeValue;
|
||||
}
|
||||
return $dateValueNew;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static function monthStringToNumber($month) {
|
||||
$monthIndex = 1;
|
||||
foreach(self::$_monthNames as $shortMonthName => $longMonthName) {
|
||||
if (($month === $longMonthName) || ($month === $shortMonthName)) {
|
||||
return $monthIndex;
|
||||
}
|
||||
++$monthIndex;
|
||||
}
|
||||
return $month;
|
||||
}
|
||||
|
||||
public static function dayStringToNumber($day) {
|
||||
$strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day));
|
||||
if (is_numeric($strippedDayValue)) {
|
||||
return $strippedDayValue;
|
||||
}
|
||||
return $day;
|
||||
}
|
||||
|
||||
}
|
272
extend/phpexcel/PHPExcel/Shared/Drawing.php
Executable file
272
extend/phpexcel/PHPExcel/Shared/Drawing.php
Executable file
@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Drawing
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Drawing
|
||||
{
|
||||
/**
|
||||
* Convert pixels to EMU
|
||||
*
|
||||
* @param int $pValue Value in pixels
|
||||
* @return int Value in EMU
|
||||
*/
|
||||
public static function pixelsToEMU($pValue = 0) {
|
||||
return round($pValue * 9525);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert EMU to pixels
|
||||
*
|
||||
* @param int $pValue Value in EMU
|
||||
* @return int Value in pixels
|
||||
*/
|
||||
public static function EMUToPixels($pValue = 0) {
|
||||
if ($pValue != 0) {
|
||||
return round($pValue / 9525);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert pixels to column width. Exact algorithm not known.
|
||||
* By inspection of a real Excel file using Calibri 11, one finds 1000px ~ 142.85546875
|
||||
* This gives a conversion factor of 7. Also, we assume that pixels and font size are proportional.
|
||||
*
|
||||
* @param int $pValue Value in pixels
|
||||
* @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook
|
||||
* @return int Value in cell dimension
|
||||
*/
|
||||
public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) {
|
||||
// Font name and size
|
||||
$name = $pDefaultFont->getName();
|
||||
$size = $pDefaultFont->getSize();
|
||||
|
||||
if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) {
|
||||
// Exact width can be determined
|
||||
$colWidth = $pValue
|
||||
* PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']
|
||||
/ PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'];
|
||||
} else {
|
||||
// We don't have data for this particular font and size, use approximation by
|
||||
// extrapolating from Calibri 11
|
||||
$colWidth = $pValue * 11
|
||||
* PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width']
|
||||
/ PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size;
|
||||
}
|
||||
|
||||
return $colWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert column width from (intrinsic) Excel units to pixels
|
||||
*
|
||||
* @param float $pValue Value in cell dimension
|
||||
* @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook
|
||||
* @return int Value in pixels
|
||||
*/
|
||||
public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) {
|
||||
// Font name and size
|
||||
$name = $pDefaultFont->getName();
|
||||
$size = $pDefaultFont->getSize();
|
||||
|
||||
if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) {
|
||||
// Exact width can be determined
|
||||
$colWidth = $pValue
|
||||
* PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']
|
||||
/ PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'];
|
||||
|
||||
} else {
|
||||
// We don't have data for this particular font and size, use approximation by
|
||||
// extrapolating from Calibri 11
|
||||
$colWidth = $pValue * $size
|
||||
* PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px']
|
||||
/ PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11;
|
||||
}
|
||||
|
||||
// Round pixels to closest integer
|
||||
$colWidth = (int) round($colWidth);
|
||||
|
||||
return $colWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert pixels to points
|
||||
*
|
||||
* @param int $pValue Value in pixels
|
||||
* @return int Value in points
|
||||
*/
|
||||
public static function pixelsToPoints($pValue = 0) {
|
||||
return $pValue * 0.67777777;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert points to pixels
|
||||
*
|
||||
* @param int $pValue Value in points
|
||||
* @return int Value in pixels
|
||||
*/
|
||||
public static function pointsToPixels($pValue = 0) {
|
||||
if ($pValue != 0) {
|
||||
return (int) ceil($pValue * 1.333333333);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert degrees to angle
|
||||
*
|
||||
* @param int $pValue Degrees
|
||||
* @return int Angle
|
||||
*/
|
||||
public static function degreesToAngle($pValue = 0) {
|
||||
return (int)round($pValue * 60000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert angle to degrees
|
||||
*
|
||||
* @param int $pValue Angle
|
||||
* @return int Degrees
|
||||
*/
|
||||
public static function angleToDegrees($pValue = 0) {
|
||||
if ($pValue != 0) {
|
||||
return round($pValue / 60000);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new image from file. By alexander at alexauto dot nl
|
||||
*
|
||||
* @link http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214
|
||||
* @param string $filename Path to Windows DIB (BMP) image
|
||||
* @return resource
|
||||
*/
|
||||
public static function imagecreatefrombmp($p_sFile)
|
||||
{
|
||||
// Load the image into a string
|
||||
$file = fopen($p_sFile,"rb");
|
||||
$read = fread($file,10);
|
||||
while(!feof($file)&&($read<>""))
|
||||
$read .= fread($file,1024);
|
||||
|
||||
$temp = unpack("H*",$read);
|
||||
$hex = $temp[1];
|
||||
$header = substr($hex,0,108);
|
||||
|
||||
// Process the header
|
||||
// Structure: http://www.fastgraph.com/help/bmp_header_format.html
|
||||
if (substr($header,0,4)=="424d")
|
||||
{
|
||||
// Cut it in parts of 2 bytes
|
||||
$header_parts = str_split($header,2);
|
||||
|
||||
// Get the width 4 bytes
|
||||
$width = hexdec($header_parts[19].$header_parts[18]);
|
||||
|
||||
// Get the height 4 bytes
|
||||
$height = hexdec($header_parts[23].$header_parts[22]);
|
||||
|
||||
// Unset the header params
|
||||
unset($header_parts);
|
||||
}
|
||||
|
||||
// Define starting X and Y
|
||||
$x = 0;
|
||||
$y = 1;
|
||||
|
||||
// Create newimage
|
||||
$image = imagecreatetruecolor($width,$height);
|
||||
|
||||
// Grab the body from the image
|
||||
$body = substr($hex,108);
|
||||
|
||||
// Calculate if padding at the end-line is needed
|
||||
// Divided by two to keep overview.
|
||||
// 1 byte = 2 HEX-chars
|
||||
$body_size = (strlen($body)/2);
|
||||
$header_size = ($width*$height);
|
||||
|
||||
// Use end-line padding? Only when needed
|
||||
$usePadding = ($body_size>($header_size*3)+4);
|
||||
|
||||
// Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption
|
||||
// Calculate the next DWORD-position in the body
|
||||
for ($i=0;$i<$body_size;$i+=3)
|
||||
{
|
||||
// Calculate line-ending and padding
|
||||
if ($x>=$width)
|
||||
{
|
||||
// If padding needed, ignore image-padding
|
||||
// Shift i to the ending of the current 32-bit-block
|
||||
if ($usePadding)
|
||||
$i += $width%4;
|
||||
|
||||
// Reset horizontal position
|
||||
$x = 0;
|
||||
|
||||
// Raise the height-position (bottom-up)
|
||||
$y++;
|
||||
|
||||
// Reached the image-height? Break the for-loop
|
||||
if ($y>$height)
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculation of the RGB-pixel (defined as BGR in image-data)
|
||||
// Define $i_pos as absolute position in the body
|
||||
$i_pos = $i*2;
|
||||
$r = hexdec($body[$i_pos+4].$body[$i_pos+5]);
|
||||
$g = hexdec($body[$i_pos+2].$body[$i_pos+3]);
|
||||
$b = hexdec($body[$i_pos].$body[$i_pos+1]);
|
||||
|
||||
// Calculate and draw the pixel
|
||||
$color = imagecolorallocate($image,$r,$g,$b);
|
||||
imagesetpixel($image,$x,$height-$y,$color);
|
||||
|
||||
// Raise the horizontal position
|
||||
$x++;
|
||||
}
|
||||
|
||||
// Unset the body / free the memory
|
||||
unset($body);
|
||||
|
||||
// Return image-object
|
||||
return $image;
|
||||
}
|
||||
|
||||
}
|
91
extend/phpexcel/PHPExcel/Shared/Escher.php
Executable file
91
extend/phpexcel/PHPExcel/Shared/Escher.php
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher
|
||||
{
|
||||
/**
|
||||
* Drawing Group Container
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DggContainer
|
||||
*/
|
||||
private $_dggContainer;
|
||||
|
||||
/**
|
||||
* Drawing Container
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DgContainer
|
||||
*/
|
||||
private $_dgContainer;
|
||||
|
||||
/**
|
||||
* Get Drawing Group Container
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DgContainer
|
||||
*/
|
||||
public function getDggContainer()
|
||||
{
|
||||
return $this->_dggContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Drawing Group Container
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DggContainer $dggContainer
|
||||
*/
|
||||
public function setDggContainer($dggContainer)
|
||||
{
|
||||
return $this->_dggContainer = $dggContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Drawing Container
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DgContainer
|
||||
*/
|
||||
public function getDgContainer()
|
||||
{
|
||||
return $this->_dgContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Drawing Container
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DgContainer $dgContainer
|
||||
*/
|
||||
public function setDgContainer($dgContainer)
|
||||
{
|
||||
return $this->_dgContainer = $dgContainer;
|
||||
}
|
||||
|
||||
}
|
83
extend/phpexcel/PHPExcel/Shared/Escher/DgContainer.php
Executable file
83
extend/phpexcel/PHPExcel/Shared/Escher/DgContainer.php
Executable file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher_DgContainer
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher_DgContainer
|
||||
{
|
||||
/**
|
||||
* Drawing index, 1-based.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_dgId;
|
||||
|
||||
/**
|
||||
* Last shape index in this drawing
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_lastSpId;
|
||||
|
||||
private $_spgrContainer = null;
|
||||
|
||||
public function getDgId()
|
||||
{
|
||||
return $this->_dgId;
|
||||
}
|
||||
|
||||
public function setDgId($value)
|
||||
{
|
||||
$this->_dgId = $value;
|
||||
}
|
||||
|
||||
public function getLastSpId()
|
||||
{
|
||||
return $this->_lastSpId;
|
||||
}
|
||||
|
||||
public function setLastSpId($value)
|
||||
{
|
||||
$this->_lastSpId = $value;
|
||||
}
|
||||
|
||||
public function getSpgrContainer()
|
||||
{
|
||||
return $this->_spgrContainer;
|
||||
}
|
||||
|
||||
public function setSpgrContainer($spgrContainer)
|
||||
{
|
||||
return $this->_spgrContainer = $spgrContainer;
|
||||
}
|
||||
|
||||
}
|
109
extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php
Executable file
109
extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php
Executable file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher_DgContainer_SpgrContainer
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher_DgContainer_SpgrContainer
|
||||
{
|
||||
/**
|
||||
* Parent Shape Group Container
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer
|
||||
*/
|
||||
private $_parent;
|
||||
|
||||
/**
|
||||
* Shape Container collection
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_children = array();
|
||||
|
||||
/**
|
||||
* Set parent Shape Group Container
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent
|
||||
*/
|
||||
public function setParent($parent)
|
||||
{
|
||||
$this->_parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent Shape Group Container if any
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer|null
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->_parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child. This will be either spgrContainer or spContainer
|
||||
*
|
||||
* @param mixed $child
|
||||
*/
|
||||
public function addChild($child)
|
||||
{
|
||||
$this->_children[] = $child;
|
||||
$child->setParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection of Shape Containers
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->_children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively get all spContainers within this spgrContainer
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer[]
|
||||
*/
|
||||
public function getAllSpContainers()
|
||||
{
|
||||
$allSpContainers = array();
|
||||
|
||||
foreach ($this->_children as $child) {
|
||||
if ($child instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) {
|
||||
$allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers());
|
||||
} else {
|
||||
$allSpContainers[] = $child;
|
||||
}
|
||||
}
|
||||
|
||||
return $allSpContainers;
|
||||
}
|
||||
}
|
395
extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php
Executable file
395
extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php
Executable file
@ -0,0 +1,395 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer
|
||||
{
|
||||
/**
|
||||
* Parent Shape Group Container
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer
|
||||
*/
|
||||
private $_parent;
|
||||
|
||||
/**
|
||||
* Is this a group shape?
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_spgr = false;
|
||||
|
||||
/**
|
||||
* Shape type
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_spType;
|
||||
|
||||
/**
|
||||
* Shape flag
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_spFlag;
|
||||
|
||||
/**
|
||||
* Shape index (usually group shape has index 0, and the rest: 1,2,3...)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_spId;
|
||||
|
||||
/**
|
||||
* Array of options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_OPT;
|
||||
|
||||
/**
|
||||
* Cell coordinates of upper-left corner of shape, e.g. 'A1'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_startCoordinates;
|
||||
|
||||
/**
|
||||
* Horizontal offset of upper-left corner of shape measured in 1/1024 of column width
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_startOffsetX;
|
||||
|
||||
/**
|
||||
* Vertical offset of upper-left corner of shape measured in 1/256 of row height
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_startOffsetY;
|
||||
|
||||
/**
|
||||
* Cell coordinates of bottom-right corner of shape, e.g. 'B2'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_endCoordinates;
|
||||
|
||||
/**
|
||||
* Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_endOffsetX;
|
||||
|
||||
/**
|
||||
* Vertical offset of bottom-right corner of shape measured in 1/256 of row height
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_endOffsetY;
|
||||
|
||||
/**
|
||||
* Set parent Shape Group Container
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent
|
||||
*/
|
||||
public function setParent($parent)
|
||||
{
|
||||
$this->_parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent Shape Group Container
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->_parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this is a group shape
|
||||
*
|
||||
* @param boolean $value
|
||||
*/
|
||||
public function setSpgr($value = false)
|
||||
{
|
||||
$this->_spgr = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this is a group shape
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getSpgr()
|
||||
{
|
||||
return $this->_spgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shape type
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setSpType($value)
|
||||
{
|
||||
$this->_spType = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shape type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSpType()
|
||||
{
|
||||
return $this->_spType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shape flag
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setSpFlag($value)
|
||||
{
|
||||
$this->_spFlag = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shape flag
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSpFlag()
|
||||
{
|
||||
return $this->_spFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the shape index
|
||||
*
|
||||
* @param int $value
|
||||
*/
|
||||
public function setSpId($value)
|
||||
{
|
||||
$this->_spId = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shape index
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSpId()
|
||||
{
|
||||
return $this->_spId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an option for the Shape Group Container
|
||||
*
|
||||
* @param int $property The number specifies the option
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setOPT($property, $value)
|
||||
{
|
||||
$this->_OPT[$property] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an option for the Shape Group Container
|
||||
*
|
||||
* @param int $property The number specifies the option
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOPT($property)
|
||||
{
|
||||
if (isset($this->_OPT[$property])) {
|
||||
return $this->_OPT[$property];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection of options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOPTCollection()
|
||||
{
|
||||
return $this->_OPT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cell coordinates of upper-left corner of shape
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
public function setStartCoordinates($value = 'A1')
|
||||
{
|
||||
$this->_startCoordinates = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell coordinates of upper-left corner of shape
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStartCoordinates()
|
||||
{
|
||||
return $this->_startCoordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set offset in x-direction of upper-left corner of shape measured in 1/1024 of column width
|
||||
*
|
||||
* @param int $startOffsetX
|
||||
*/
|
||||
public function setStartOffsetX($startOffsetX = 0)
|
||||
{
|
||||
$this->_startOffsetX = $startOffsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset in x-direction of upper-left corner of shape measured in 1/1024 of column width
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStartOffsetX()
|
||||
{
|
||||
return $this->_startOffsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set offset in y-direction of upper-left corner of shape measured in 1/256 of row height
|
||||
*
|
||||
* @param int $startOffsetY
|
||||
*/
|
||||
public function setStartOffsetY($startOffsetY = 0)
|
||||
{
|
||||
$this->_startOffsetY = $startOffsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset in y-direction of upper-left corner of shape measured in 1/256 of row height
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStartOffsetY()
|
||||
{
|
||||
return $this->_startOffsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cell coordinates of bottom-right corner of shape
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
public function setEndCoordinates($value = 'A1')
|
||||
{
|
||||
$this->_endCoordinates = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell coordinates of bottom-right corner of shape
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEndCoordinates()
|
||||
{
|
||||
return $this->_endCoordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width
|
||||
*
|
||||
* @param int $startOffsetX
|
||||
*/
|
||||
public function setEndOffsetX($endOffsetX = 0)
|
||||
{
|
||||
$this->_endOffsetX = $endOffsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEndOffsetX()
|
||||
{
|
||||
return $this->_endOffsetX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set offset in y-direction of bottom-right corner of shape measured in 1/256 of row height
|
||||
*
|
||||
* @param int $endOffsetY
|
||||
*/
|
||||
public function setEndOffsetY($endOffsetY = 0)
|
||||
{
|
||||
$this->_endOffsetY = $endOffsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get offset in y-direction of bottom-right corner of shape measured in 1/256 of row height
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEndOffsetY()
|
||||
{
|
||||
return $this->_endOffsetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nesting level of this spContainer. This is the number of spgrContainers between this spContainer and
|
||||
* the dgContainer. A value of 1 = immediately within first spgrContainer
|
||||
* Higher nesting level occurs if and only if spContainer is part of a shape group
|
||||
*
|
||||
* @return int Nesting level
|
||||
*/
|
||||
public function getNestingLevel()
|
||||
{
|
||||
$nestingLevel = 0;
|
||||
|
||||
$parent = $this->getParent();
|
||||
while ($parent instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) {
|
||||
++$nestingLevel;
|
||||
$parent = $parent->getParent();
|
||||
}
|
||||
|
||||
return $nestingLevel;
|
||||
}
|
||||
}
|
203
extend/phpexcel/PHPExcel/Shared/Escher/DggContainer.php
Executable file
203
extend/phpexcel/PHPExcel/Shared/Escher/DggContainer.php
Executable file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher_DggContainer
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher_DggContainer
|
||||
{
|
||||
/**
|
||||
* Maximum shape index of all shapes in all drawings increased by one
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_spIdMax;
|
||||
|
||||
/**
|
||||
* Total number of drawings saved
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_cDgSaved;
|
||||
|
||||
/**
|
||||
* Total number of shapes saved (including group shapes)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_cSpSaved;
|
||||
|
||||
/**
|
||||
* BLIP Store Container
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer
|
||||
*/
|
||||
private $_bstoreContainer;
|
||||
|
||||
/**
|
||||
* Array of options for the drawing group
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_OPT = array();
|
||||
|
||||
/**
|
||||
* Array of identifier clusters containg information about the maximum shape identifiers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_IDCLs = array();
|
||||
|
||||
/**
|
||||
* Get maximum shape index of all shapes in all drawings (plus one)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSpIdMax()
|
||||
{
|
||||
return $this->_spIdMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set maximum shape index of all shapes in all drawings (plus one)
|
||||
*
|
||||
* @param int
|
||||
*/
|
||||
public function setSpIdMax($value)
|
||||
{
|
||||
$this->_spIdMax = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total number of drawings saved
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCDgSaved()
|
||||
{
|
||||
return $this->_cDgSaved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set total number of drawings saved
|
||||
*
|
||||
* @param int
|
||||
*/
|
||||
public function setCDgSaved($value)
|
||||
{
|
||||
$this->_cDgSaved = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total number of shapes saved (including group shapes)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCSpSaved()
|
||||
{
|
||||
return $this->_cSpSaved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set total number of shapes saved (including group shapes)
|
||||
*
|
||||
* @param int
|
||||
*/
|
||||
public function setCSpSaved($value)
|
||||
{
|
||||
$this->_cSpSaved = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get BLIP Store Container
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer
|
||||
*/
|
||||
public function getBstoreContainer()
|
||||
{
|
||||
return $this->_bstoreContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set BLIP Store Container
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $bstoreContainer
|
||||
*/
|
||||
public function setBstoreContainer($bstoreContainer)
|
||||
{
|
||||
$this->_bstoreContainer = $bstoreContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an option for the drawing group
|
||||
*
|
||||
* @param int $property The number specifies the option
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setOPT($property, $value)
|
||||
{
|
||||
$this->_OPT[$property] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an option for the drawing group
|
||||
*
|
||||
* @param int $property The number specifies the option
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOPT($property)
|
||||
{
|
||||
if (isset($this->_OPT[$property])) {
|
||||
return $this->_OPT[$property];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier clusters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getIDCLs()
|
||||
{
|
||||
return $this->_IDCLs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set identifier clusters. array(<drawingId> => <max shape id>, ...)
|
||||
*
|
||||
* @param array $pValue
|
||||
*/
|
||||
public function setIDCLs($pValue)
|
||||
{
|
||||
$this->_IDCLs = $pValue;
|
||||
}
|
||||
}
|
65
extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php
Executable file
65
extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php
Executable file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher_DggContainer_BstoreContainer
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher_DggContainer_BstoreContainer
|
||||
{
|
||||
/**
|
||||
* BLIP Store Entries. Each of them holds one BLIP (Big Large Image or Picture)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_BSECollection = array();
|
||||
|
||||
/**
|
||||
* Add a BLIP Store Entry
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $BSE
|
||||
*/
|
||||
public function addBSE($BSE)
|
||||
{
|
||||
$this->_BSECollection[] = $BSE;
|
||||
$BSE->setParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection of BLIP Store Entries
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE[]
|
||||
*/
|
||||
public function getBSECollection()
|
||||
{
|
||||
return $this->_BSECollection;
|
||||
}
|
||||
|
||||
}
|
120
extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php
Executable file
120
extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php
Executable file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE
|
||||
{
|
||||
const BLIPTYPE_ERROR = 0x00;
|
||||
const BLIPTYPE_UNKNOWN = 0x01;
|
||||
const BLIPTYPE_EMF = 0x02;
|
||||
const BLIPTYPE_WMF = 0x03;
|
||||
const BLIPTYPE_PICT = 0x04;
|
||||
const BLIPTYPE_JPEG = 0x05;
|
||||
const BLIPTYPE_PNG = 0x06;
|
||||
const BLIPTYPE_DIB = 0x07;
|
||||
const BLIPTYPE_TIFF = 0x11;
|
||||
const BLIPTYPE_CMYKJPEG = 0x12;
|
||||
|
||||
/**
|
||||
* The parent BLIP Store Entry Container
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer
|
||||
*/
|
||||
private $_parent;
|
||||
|
||||
/**
|
||||
* The BLIP (Big Large Image or Picture)
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip
|
||||
*/
|
||||
private $_blip;
|
||||
|
||||
/**
|
||||
* The BLIP type
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_blipType;
|
||||
|
||||
/**
|
||||
* Set parent BLIP Store Entry Container
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $parent
|
||||
*/
|
||||
public function setParent($parent)
|
||||
{
|
||||
$this->_parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BLIP
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip
|
||||
*/
|
||||
public function getBlip()
|
||||
{
|
||||
return $this->_blip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BLIP
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip $blip
|
||||
*/
|
||||
public function setBlip($blip)
|
||||
{
|
||||
$this->_blip = $blip;
|
||||
$blip->setParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BLIP type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBlipType()
|
||||
{
|
||||
return $this->_blipType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BLIP type
|
||||
*
|
||||
* @param int
|
||||
*/
|
||||
public function setBlipType($blipType)
|
||||
{
|
||||
$this->_blipType = $blipType;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Escher
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip
|
||||
{
|
||||
/**
|
||||
* The parent BSE
|
||||
*
|
||||
* @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE
|
||||
*/
|
||||
private $_parent;
|
||||
|
||||
/**
|
||||
* Raw image data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_data;
|
||||
|
||||
/**
|
||||
* Get the raw image data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the raw image data
|
||||
*
|
||||
* @param string
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->_data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent BSE
|
||||
*
|
||||
* @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent
|
||||
*/
|
||||
public function setParent($parent)
|
||||
{
|
||||
$this->_parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent BSE
|
||||
*
|
||||
* @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->_parent;
|
||||
}
|
||||
|
||||
}
|
317
extend/phpexcel/PHPExcel/Shared/Excel5.php
Executable file
317
extend/phpexcel/PHPExcel/Shared/Excel5.php
Executable file
@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Excel5
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Excel5
|
||||
{
|
||||
/**
|
||||
* Get the width of a column in pixels. We use the relationship y = ceil(7x) where
|
||||
* x is the width in intrinsic Excel units (measuring width in number of normal characters)
|
||||
* This holds for Arial 10
|
||||
*
|
||||
* @param PHPExcel_Worksheet $sheet The sheet
|
||||
* @param string $col The column
|
||||
* @return integer The width in pixels
|
||||
*/
|
||||
public static function sizeCol($sheet, $col = 'A')
|
||||
{
|
||||
// default font of the workbook
|
||||
$font = $sheet->getParent()->getDefaultStyle()->getFont();
|
||||
|
||||
$columnDimensions = $sheet->getColumnDimensions();
|
||||
|
||||
// first find the true column width in pixels (uncollapsed and unhidden)
|
||||
if ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) {
|
||||
|
||||
// then we have column dimension with explicit width
|
||||
$columnDimension = $columnDimensions[$col];
|
||||
$width = $columnDimension->getWidth();
|
||||
$pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font);
|
||||
|
||||
} else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) {
|
||||
|
||||
// then we have default column dimension with explicit width
|
||||
$defaultColumnDimension = $sheet->getDefaultColumnDimension();
|
||||
$width = $defaultColumnDimension->getWidth();
|
||||
$pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font);
|
||||
|
||||
} else {
|
||||
|
||||
// we don't even have any default column dimension. Width depends on default font
|
||||
$pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true);
|
||||
}
|
||||
|
||||
// now find the effective column width in pixels
|
||||
if (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) {
|
||||
$effectivePixelWidth = 0;
|
||||
} else {
|
||||
$effectivePixelWidth = $pixelWidth;
|
||||
}
|
||||
|
||||
return $effectivePixelWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the height of a cell from user's units to pixels. By interpolation
|
||||
* the relationship is: y = 4/3x. If the height hasn't been set by the user we
|
||||
* use the default value. If the row is hidden we use a value of zero.
|
||||
*
|
||||
* @param PHPExcel_Worksheet $sheet The sheet
|
||||
* @param integer $row The row index (1-based)
|
||||
* @return integer The width in pixels
|
||||
*/
|
||||
public static function sizeRow($sheet, $row = 1)
|
||||
{
|
||||
// default font of the workbook
|
||||
$font = $sheet->getParent()->getDefaultStyle()->getFont();
|
||||
|
||||
$rowDimensions = $sheet->getRowDimensions();
|
||||
|
||||
// first find the true row height in pixels (uncollapsed and unhidden)
|
||||
if ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) {
|
||||
|
||||
// then we have a row dimension
|
||||
$rowDimension = $rowDimensions[$row];
|
||||
$rowHeight = $rowDimension->getRowHeight();
|
||||
$pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10
|
||||
|
||||
} else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) {
|
||||
|
||||
// then we have a default row dimension with explicit height
|
||||
$defaultRowDimension = $sheet->getDefaultRowDimension();
|
||||
$rowHeight = $defaultRowDimension->getRowHeight();
|
||||
$pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight);
|
||||
|
||||
} else {
|
||||
|
||||
// we don't even have any default row dimension. Height depends on default font
|
||||
$pointRowHeight = PHPExcel_Shared_Font::getDefaultRowHeightByFont($font);
|
||||
$pixelRowHeight = PHPExcel_Shared_Font::fontSizeToPixels($pointRowHeight);
|
||||
|
||||
}
|
||||
|
||||
// now find the effective row height in pixels
|
||||
if ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) {
|
||||
$effectivePixelRowHeight = 0;
|
||||
} else {
|
||||
$effectivePixelRowHeight = $pixelRowHeight;
|
||||
}
|
||||
|
||||
return $effectivePixelRowHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the horizontal distance in pixels between two anchors
|
||||
* The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets
|
||||
*
|
||||
* @param PHPExcel_Worksheet $sheet
|
||||
* @param string $startColumn
|
||||
* @param integer $startOffsetX Offset within start cell measured in 1/1024 of the cell width
|
||||
* @param string $endColumn
|
||||
* @param integer $endOffsetX Offset within end cell measured in 1/1024 of the cell width
|
||||
* @return integer Horizontal measured in pixels
|
||||
*/
|
||||
public static function getDistanceX(PHPExcel_Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0)
|
||||
{
|
||||
$distanceX = 0;
|
||||
|
||||
// add the widths of the spanning columns
|
||||
$startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; // 1-based
|
||||
$endColumnIndex = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; // 1-based
|
||||
for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) {
|
||||
$distanceX += self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($i));
|
||||
}
|
||||
|
||||
// correct for offsetX in startcell
|
||||
$distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024);
|
||||
|
||||
// correct for offsetX in endcell
|
||||
$distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024));
|
||||
|
||||
return $distanceX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the vertical distance in pixels between two anchors
|
||||
* The distanceY is found as sum of all the spanning rows minus two offsets
|
||||
*
|
||||
* @param PHPExcel_Worksheet $sheet
|
||||
* @param integer $startRow (1-based)
|
||||
* @param integer $startOffsetY Offset within start cell measured in 1/256 of the cell height
|
||||
* @param integer $endRow (1-based)
|
||||
* @param integer $endOffsetY Offset within end cell measured in 1/256 of the cell height
|
||||
* @return integer Vertical distance measured in pixels
|
||||
*/
|
||||
public static function getDistanceY(PHPExcel_Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0)
|
||||
{
|
||||
$distanceY = 0;
|
||||
|
||||
// add the widths of the spanning rows
|
||||
for ($row = $startRow; $row <= $endRow; ++$row) {
|
||||
$distanceY += self::sizeRow($sheet, $row);
|
||||
}
|
||||
|
||||
// correct for offsetX in startcell
|
||||
$distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256);
|
||||
|
||||
// correct for offsetX in endcell
|
||||
$distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256));
|
||||
|
||||
return $distanceY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert 1-cell anchor coordinates to 2-cell anchor coordinates
|
||||
* This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications
|
||||
*
|
||||
* Calculate the vertices that define the position of the image as required by
|
||||
* the OBJ record.
|
||||
*
|
||||
* +------------+------------+
|
||||
* | A | B |
|
||||
* +-----+------------+------------+
|
||||
* | |(x1,y1) | |
|
||||
* | 1 |(A1)._______|______ |
|
||||
* | | | | |
|
||||
* | | | | |
|
||||
* +-----+----| BITMAP |-----+
|
||||
* | | | | |
|
||||
* | 2 | |______________. |
|
||||
* | | | (B2)|
|
||||
* | | | (x2,y2)|
|
||||
* +---- +------------+------------+
|
||||
*
|
||||
* Example of a bitmap that covers some of the area from cell A1 to cell B2.
|
||||
*
|
||||
* Based on the width and height of the bitmap we need to calculate 8 vars:
|
||||
* $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2.
|
||||
* The width and height of the cells are also variable and have to be taken into
|
||||
* account.
|
||||
* The values of $col_start and $row_start are passed in from the calling
|
||||
* function. The values of $col_end and $row_end are calculated by subtracting
|
||||
* the width and height of the bitmap from the width and height of the
|
||||
* underlying cells.
|
||||
* The vertices are expressed as a percentage of the underlying cell width as
|
||||
* follows (rhs values are in pixels):
|
||||
*
|
||||
* x1 = X / W *1024
|
||||
* y1 = Y / H *256
|
||||
* x2 = (X-1) / W *1024
|
||||
* y2 = (Y-1) / H *256
|
||||
*
|
||||
* Where: X is distance from the left side of the underlying cell
|
||||
* Y is distance from the top of the underlying cell
|
||||
* W is the width of the cell
|
||||
* H is the height of the cell
|
||||
*
|
||||
* @param PHPExcel_Worksheet $sheet
|
||||
* @param string $coordinates E.g. 'A1'
|
||||
* @param integer $offsetX Horizontal offset in pixels
|
||||
* @param integer $offsetY Vertical offset in pixels
|
||||
* @param integer $width Width in pixels
|
||||
* @param integer $height Height in pixels
|
||||
* @return array
|
||||
*/
|
||||
public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)
|
||||
{
|
||||
list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinates);
|
||||
$col_start = PHPExcel_Cell::columnIndexFromString($column) - 1;
|
||||
$row_start = $row - 1;
|
||||
|
||||
$x1 = $offsetX;
|
||||
$y1 = $offsetY;
|
||||
|
||||
// Initialise end cell to the same as the start cell
|
||||
$col_end = $col_start; // Col containing lower right corner of object
|
||||
$row_end = $row_start; // Row containing bottom right corner of object
|
||||
|
||||
// Zero the specified offset if greater than the cell dimensions
|
||||
if ($x1 >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) {
|
||||
$x1 = 0;
|
||||
}
|
||||
if ($y1 >= self::sizeRow($sheet, $row_start + 1)) {
|
||||
$y1 = 0;
|
||||
}
|
||||
|
||||
$width = $width + $x1 -1;
|
||||
$height = $height + $y1 -1;
|
||||
|
||||
// Subtract the underlying cell widths to find the end cell of the image
|
||||
while ($width >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) {
|
||||
$width -= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end));
|
||||
++$col_end;
|
||||
}
|
||||
|
||||
// Subtract the underlying cell heights to find the end cell of the image
|
||||
while ($height >= self::sizeRow($sheet, $row_end + 1)) {
|
||||
$height -= self::sizeRow($sheet, $row_end + 1);
|
||||
++$row_end;
|
||||
}
|
||||
|
||||
// Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell
|
||||
// with zero height or width.
|
||||
if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) {
|
||||
return;
|
||||
}
|
||||
if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) {
|
||||
return;
|
||||
}
|
||||
if (self::sizeRow($sheet, $row_start + 1) == 0) {
|
||||
return;
|
||||
}
|
||||
if (self::sizeRow($sheet, $row_end + 1) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert the pixel values to the percentage value expected by Excel
|
||||
$x1 = $x1 / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024;
|
||||
$y1 = $y1 / self::sizeRow($sheet, $row_start + 1) * 256;
|
||||
$x2 = ($width + 1) / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object
|
||||
$y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1) * 256; // Distance to bottom of object
|
||||
|
||||
$startCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_start) . ($row_start + 1);
|
||||
$endCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_end) . ($row_end + 1);
|
||||
|
||||
$twoAnchor = array(
|
||||
'startCoordinates' => $startCoordinates,
|
||||
'startOffsetX' => $x1,
|
||||
'startOffsetY' => $y1,
|
||||
'endCoordinates' => $endCoordinates,
|
||||
'endOffsetX' => $x2,
|
||||
'endOffsetY' => $y2,
|
||||
);
|
||||
|
||||
return $twoAnchor;
|
||||
}
|
||||
|
||||
}
|
178
extend/phpexcel/PHPExcel/Shared/File.php
Executable file
178
extend/phpexcel/PHPExcel/Shared/File.php
Executable file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_File
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_File
|
||||
{
|
||||
/*
|
||||
* Use Temp or File Upload Temp for temporary files
|
||||
*
|
||||
* @protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected static $_useUploadTempDirectory = FALSE;
|
||||
|
||||
|
||||
/**
|
||||
* Set the flag indicating whether the File Upload Temp directory should be used for temporary files
|
||||
*
|
||||
* @param boolean $useUploadTempDir Use File Upload Temporary directory (true or false)
|
||||
*/
|
||||
public static function setUseUploadTempDirectory($useUploadTempDir = FALSE) {
|
||||
self::$_useUploadTempDirectory = (boolean) $useUploadTempDir;
|
||||
} // function setUseUploadTempDirectory()
|
||||
|
||||
|
||||
/**
|
||||
* Get the flag indicating whether the File Upload Temp directory should be used for temporary files
|
||||
*
|
||||
* @return boolean Use File Upload Temporary directory (true or false)
|
||||
*/
|
||||
public static function getUseUploadTempDirectory() {
|
||||
return self::$_useUploadTempDirectory;
|
||||
} // function getUseUploadTempDirectory()
|
||||
|
||||
|
||||
/**
|
||||
* Verify if a file exists
|
||||
*
|
||||
* @param string $pFilename Filename
|
||||
* @return bool
|
||||
*/
|
||||
public static function file_exists($pFilename) {
|
||||
// Sick construction, but it seems that
|
||||
// file_exists returns strange values when
|
||||
// doing the original file_exists on ZIP archives...
|
||||
if ( strtolower(substr($pFilename, 0, 3)) == 'zip' ) {
|
||||
// Open ZIP file and verify if the file exists
|
||||
$zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6);
|
||||
$archiveFile = substr($pFilename, strpos($pFilename, '#') + 1);
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipFile) === true) {
|
||||
$returnValue = ($zip->getFromName($archiveFile) !== false);
|
||||
$zip->close();
|
||||
return $returnValue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Regular file_exists
|
||||
return file_exists($pFilename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns canonicalized absolute pathname, also for ZIP archives
|
||||
*
|
||||
* @param string $pFilename
|
||||
* @return string
|
||||
*/
|
||||
public static function realpath($pFilename) {
|
||||
// Returnvalue
|
||||
$returnValue = '';
|
||||
|
||||
// Try using realpath()
|
||||
if (file_exists($pFilename)) {
|
||||
$returnValue = realpath($pFilename);
|
||||
}
|
||||
|
||||
// Found something?
|
||||
if ($returnValue == '' || ($returnValue === NULL)) {
|
||||
$pathArray = explode('/' , $pFilename);
|
||||
while(in_array('..', $pathArray) && $pathArray[0] != '..') {
|
||||
for ($i = 0; $i < count($pathArray); ++$i) {
|
||||
if ($pathArray[$i] == '..' && $i > 0) {
|
||||
unset($pathArray[$i]);
|
||||
unset($pathArray[$i - 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$returnValue = implode('/', $pathArray);
|
||||
}
|
||||
|
||||
// Return
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the systems temporary directory.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function sys_get_temp_dir()
|
||||
{
|
||||
if (self::$_useUploadTempDirectory) {
|
||||
// use upload-directory when defined to allow running on environments having very restricted
|
||||
// open_basedir configs
|
||||
if (ini_get('upload_tmp_dir') !== FALSE) {
|
||||
if ($temp = ini_get('upload_tmp_dir')) {
|
||||
if (file_exists($temp))
|
||||
return realpath($temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sys_get_temp_dir is only available since PHP 5.2.1
|
||||
// http://php.net/manual/en/function.sys-get-temp-dir.php#94119
|
||||
if ( !function_exists('sys_get_temp_dir')) {
|
||||
if ($temp = getenv('TMP') ) {
|
||||
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
|
||||
}
|
||||
if ($temp = getenv('TEMP') ) {
|
||||
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
|
||||
}
|
||||
if ($temp = getenv('TMPDIR') ) {
|
||||
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
|
||||
}
|
||||
|
||||
// trick for creating a file in system's temporary dir
|
||||
// without knowing the path of the system's temporary dir
|
||||
$temp = tempnam(__FILE__, '');
|
||||
if (file_exists($temp)) {
|
||||
unlink($temp);
|
||||
return realpath(dirname($temp));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// use ordinary built-in PHP function
|
||||
// There should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only
|
||||
// be called if we're running 5.2.1 or earlier
|
||||
return realpath(sys_get_temp_dir());
|
||||
}
|
||||
|
||||
}
|
775
extend/phpexcel/PHPExcel/Shared/Font.php
Executable file
775
extend/phpexcel/PHPExcel/Shared/Font.php
Executable file
@ -0,0 +1,775 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_Font
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_Font
|
||||
{
|
||||
/* Methods for resolving autosize value */
|
||||
const AUTOSIZE_METHOD_APPROX = 'approx';
|
||||
const AUTOSIZE_METHOD_EXACT = 'exact';
|
||||
|
||||
private static $_autoSizeMethods = array(
|
||||
self::AUTOSIZE_METHOD_APPROX,
|
||||
self::AUTOSIZE_METHOD_EXACT,
|
||||
);
|
||||
|
||||
/** Character set codes used by BIFF5-8 in Font records */
|
||||
const CHARSET_ANSI_LATIN = 0x00;
|
||||
const CHARSET_SYSTEM_DEFAULT = 0x01;
|
||||
const CHARSET_SYMBOL = 0x02;
|
||||
const CHARSET_APPLE_ROMAN = 0x4D;
|
||||
const CHARSET_ANSI_JAPANESE_SHIFTJIS = 0x80;
|
||||
const CHARSET_ANSI_KOREAN_HANGUL = 0x81;
|
||||
const CHARSET_ANSI_KOREAN_JOHAB = 0x82;
|
||||
const CHARSET_ANSI_CHINESE_SIMIPLIFIED = 0x86; // gb2312
|
||||
const CHARSET_ANSI_CHINESE_TRADITIONAL = 0x88; // big5
|
||||
const CHARSET_ANSI_GREEK = 0xA1;
|
||||
const CHARSET_ANSI_TURKISH = 0xA2;
|
||||
const CHARSET_ANSI_VIETNAMESE = 0xA3;
|
||||
const CHARSET_ANSI_HEBREW = 0xB1;
|
||||
const CHARSET_ANSI_ARABIC = 0xB2;
|
||||
const CHARSET_ANSI_BALTIC = 0xBA;
|
||||
const CHARSET_ANSI_CYRILLIC = 0xCC;
|
||||
const CHARSET_ANSI_THAI = 0xDD;
|
||||
const CHARSET_ANSI_LATIN_II = 0xEE;
|
||||
const CHARSET_OEM_LATIN_I = 0xFF;
|
||||
|
||||
// XXX: Constants created!
|
||||
/** Font filenames */
|
||||
const ARIAL = 'arial.ttf';
|
||||
const ARIAL_BOLD = 'arialbd.ttf';
|
||||
const ARIAL_ITALIC = 'ariali.ttf';
|
||||
const ARIAL_BOLD_ITALIC = 'arialbi.ttf';
|
||||
|
||||
const CALIBRI = 'CALIBRI.TTF';
|
||||
const CALIBRI_BOLD = 'CALIBRIB.TTF';
|
||||
const CALIBRI_ITALIC = 'CALIBRII.TTF';
|
||||
const CALIBRI_BOLD_ITALIC = 'CALIBRIZ.TTF';
|
||||
|
||||
const COMIC_SANS_MS = 'comic.ttf';
|
||||
const COMIC_SANS_MS_BOLD = 'comicbd.ttf';
|
||||
|
||||
const COURIER_NEW = 'cour.ttf';
|
||||
const COURIER_NEW_BOLD = 'courbd.ttf';
|
||||
const COURIER_NEW_ITALIC = 'couri.ttf';
|
||||
const COURIER_NEW_BOLD_ITALIC = 'courbi.ttf';
|
||||
|
||||
const GEORGIA = 'georgia.ttf';
|
||||
const GEORGIA_BOLD = 'georgiab.ttf';
|
||||
const GEORGIA_ITALIC = 'georgiai.ttf';
|
||||
const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf';
|
||||
|
||||
const IMPACT = 'impact.ttf';
|
||||
|
||||
const LIBERATION_SANS = 'LiberationSans-Regular.ttf';
|
||||
const LIBERATION_SANS_BOLD = 'LiberationSans-Bold.ttf';
|
||||
const LIBERATION_SANS_ITALIC = 'LiberationSans-Italic.ttf';
|
||||
const LIBERATION_SANS_BOLD_ITALIC = 'LiberationSans-BoldItalic.ttf';
|
||||
|
||||
const LUCIDA_CONSOLE = 'lucon.ttf';
|
||||
const LUCIDA_SANS_UNICODE = 'l_10646.ttf';
|
||||
|
||||
const MICROSOFT_SANS_SERIF = 'micross.ttf';
|
||||
|
||||
const PALATINO_LINOTYPE = 'pala.ttf';
|
||||
const PALATINO_LINOTYPE_BOLD = 'palab.ttf';
|
||||
const PALATINO_LINOTYPE_ITALIC = 'palai.ttf';
|
||||
const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.ttf';
|
||||
|
||||
const SYMBOL = 'symbol.ttf';
|
||||
|
||||
const TAHOMA = 'tahoma.ttf';
|
||||
const TAHOMA_BOLD = 'tahomabd.ttf';
|
||||
|
||||
const TIMES_NEW_ROMAN = 'times.ttf';
|
||||
const TIMES_NEW_ROMAN_BOLD = 'timesbd.ttf';
|
||||
const TIMES_NEW_ROMAN_ITALIC = 'timesi.ttf';
|
||||
const TIMES_NEW_ROMAN_BOLD_ITALIC = 'timesbi.ttf';
|
||||
|
||||
const TREBUCHET_MS = 'trebuc.ttf';
|
||||
const TREBUCHET_MS_BOLD = 'trebucbd.ttf';
|
||||
const TREBUCHET_MS_ITALIC = 'trebucit.ttf';
|
||||
const TREBUCHET_MS_BOLD_ITALIC = 'trebucbi.ttf';
|
||||
|
||||
const VERDANA = 'verdana.ttf';
|
||||
const VERDANA_BOLD = 'verdanab.ttf';
|
||||
const VERDANA_ITALIC = 'verdanai.ttf';
|
||||
const VERDANA_BOLD_ITALIC = 'verdanaz.ttf';
|
||||
|
||||
/**
|
||||
* AutoSize method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $autoSizeMethod = self::AUTOSIZE_METHOD_APPROX;
|
||||
|
||||
/**
|
||||
* Path to folder containing TrueType font .ttf files
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $trueTypeFontPath = null;
|
||||
|
||||
/**
|
||||
* How wide is a default column for a given default font and size?
|
||||
* Empirical data found by inspecting real Excel files and reading off the pixel width
|
||||
* in Microsoft Office Excel 2007.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $defaultColumnWidths = array(
|
||||
'Arial' => array(
|
||||
1 => array('px' => 24, 'width' => 12.00000000),
|
||||
2 => array('px' => 24, 'width' => 12.00000000),
|
||||
3 => array('px' => 32, 'width' => 10.66406250),
|
||||
4 => array('px' => 32, 'width' => 10.66406250),
|
||||
5 => array('px' => 40, 'width' => 10.00000000),
|
||||
6 => array('px' => 48, 'width' => 9.59765625),
|
||||
7 => array('px' => 48, 'width' => 9.59765625),
|
||||
8 => array('px' => 56, 'width' => 9.33203125),
|
||||
9 => array('px' => 64, 'width' => 9.14062500),
|
||||
10 => array('px' => 64, 'width' => 9.14062500),
|
||||
),
|
||||
'Calibri' => array(
|
||||
1 => array('px' => 24, 'width' => 12.00000000),
|
||||
2 => array('px' => 24, 'width' => 12.00000000),
|
||||
3 => array('px' => 32, 'width' => 10.66406250),
|
||||
4 => array('px' => 32, 'width' => 10.66406250),
|
||||
5 => array('px' => 40, 'width' => 10.00000000),
|
||||
6 => array('px' => 48, 'width' => 9.59765625),
|
||||
7 => array('px' => 48, 'width' => 9.59765625),
|
||||
8 => array('px' => 56, 'width' => 9.33203125),
|
||||
9 => array('px' => 56, 'width' => 9.33203125),
|
||||
10 => array('px' => 64, 'width' => 9.14062500),
|
||||
11 => array('px' => 64, 'width' => 9.14062500),
|
||||
),
|
||||
'Verdana' => array(
|
||||
1 => array('px' => 24, 'width' => 12.00000000),
|
||||
2 => array('px' => 24, 'width' => 12.00000000),
|
||||
3 => array('px' => 32, 'width' => 10.66406250),
|
||||
4 => array('px' => 32, 'width' => 10.66406250),
|
||||
5 => array('px' => 40, 'width' => 10.00000000),
|
||||
6 => array('px' => 48, 'width' => 9.59765625),
|
||||
7 => array('px' => 48, 'width' => 9.59765625),
|
||||
8 => array('px' => 64, 'width' => 9.14062500),
|
||||
9 => array('px' => 72, 'width' => 9.00000000),
|
||||
10 => array('px' => 72, 'width' => 9.00000000),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Set autoSize method
|
||||
*
|
||||
* @param string $pValue
|
||||
* @return boolean Success or failure
|
||||
*/
|
||||
public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX)
|
||||
{
|
||||
if (!in_array($pValue,self::$_autoSizeMethods)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self::$autoSizeMethod = $pValue;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get autoSize method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getAutoSizeMethod()
|
||||
{
|
||||
return self::$autoSizeMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to the folder containing .ttf files. There should be a trailing slash.
|
||||
* Typical locations on variout some platforms:
|
||||
* <ul>
|
||||
* <li>C:/Windows/Fonts/</li>
|
||||
* <li>/usr/share/fonts/truetype/</li>
|
||||
* <li>~/.fonts/</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param string $pValue
|
||||
*/
|
||||
public static function setTrueTypeFontPath($pValue = '')
|
||||
{
|
||||
self::$trueTypeFontPath = $pValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the folder containing .ttf files.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTrueTypeFontPath()
|
||||
{
|
||||
return self::$trueTypeFontPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate an (approximate) OpenXML column width, based on font size and text contained
|
||||
*
|
||||
* @param PHPExcel_Style_Font $font Font object
|
||||
* @param PHPExcel_RichText|string $cellText Text to calculate width
|
||||
* @param integer $rotation Rotation angle
|
||||
* @param PHPExcel_Style_Font|NULL $defaultFont Font object
|
||||
* @return integer Column width
|
||||
*/
|
||||
public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) {
|
||||
|
||||
// If it is rich text, use plain text
|
||||
if ($cellText instanceof PHPExcel_RichText) {
|
||||
$cellText = $cellText->getPlainText();
|
||||
}
|
||||
|
||||
// Special case if there are one or more newline characters ("\n")
|
||||
if (strpos($cellText, "\n") !== false) {
|
||||
$lineTexts = explode("\n", $cellText);
|
||||
$lineWitdhs = array();
|
||||
foreach ($lineTexts as $lineText) {
|
||||
$lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont);
|
||||
}
|
||||
return max($lineWidths); // width of longest line in cell
|
||||
}
|
||||
|
||||
// Try to get the exact text width in pixels
|
||||
try {
|
||||
// If autosize method is set to 'approx', use approximation
|
||||
if (self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX) {
|
||||
throw new PHPExcel_Exception('AutoSize method is set to approx');
|
||||
}
|
||||
|
||||
// Width of text in pixels excl. padding
|
||||
$columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation);
|
||||
|
||||
// Excel adds some padding, use 1.07 of the width of an 'n' glyph
|
||||
$columnWidth += ceil(self::getTextWidthPixelsExact('0', $font, 0) * 1.07); // pixels incl. padding
|
||||
|
||||
} catch (PHPExcel_Exception $e) {
|
||||
// Width of text in pixels excl. padding, approximation
|
||||
$columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation);
|
||||
|
||||
// Excel adds some padding, just use approx width of 'n' glyph
|
||||
$columnWidth += self::getTextWidthPixelsApprox('n', $font, 0);
|
||||
}
|
||||
|
||||
// Convert from pixel width to column width
|
||||
$columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont);
|
||||
|
||||
// Return
|
||||
return round($columnWidth, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get GD text width in pixels for a string of text in a certain font at a certain rotation angle
|
||||
*
|
||||
* @param string $text
|
||||
* @param PHPExcel_Style_Font
|
||||
* @param int $rotation
|
||||
* @return int
|
||||
* @throws PHPExcel_Exception
|
||||
*/
|
||||
public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) {
|
||||
if (!function_exists('imagettfbbox')) {
|
||||
throw new PHPExcel_Exception('GD library needs to be enabled');
|
||||
}
|
||||
|
||||
// font size should really be supplied in pixels in GD2,
|
||||
// but since GD2 seems to assume 72dpi, pixels and points are the same
|
||||
$fontFile = self::getTrueTypeFontFileFromFont($font);
|
||||
$textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text);
|
||||
|
||||
// Get corners positions
|
||||
$lowerLeftCornerX = $textBox[0];
|
||||
$lowerLeftCornerY = $textBox[1];
|
||||
$lowerRightCornerX = $textBox[2];
|
||||
$lowerRightCornerY = $textBox[3];
|
||||
$upperRightCornerX = $textBox[4];
|
||||
$upperRightCornerY = $textBox[5];
|
||||
$upperLeftCornerX = $textBox[6];
|
||||
$upperLeftCornerY = $textBox[7];
|
||||
|
||||
// Consider the rotation when calculating the width
|
||||
$textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX);
|
||||
|
||||
return $textWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get approximate width in pixels for a string of text in a certain font at a certain rotation angle
|
||||
*
|
||||
* @param string $columnText
|
||||
* @param PHPExcel_Style_Font $font
|
||||
* @param int $rotation
|
||||
* @return int Text width in pixels (no padding added)
|
||||
*/
|
||||
public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font $font = null, $rotation = 0)
|
||||
{
|
||||
$fontName = $font->getName();
|
||||
$fontSize = $font->getSize();
|
||||
|
||||
// Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size.
|
||||
switch ($fontName) {
|
||||
case 'Calibri':
|
||||
// value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font.
|
||||
$columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText));
|
||||
$columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size
|
||||
break;
|
||||
|
||||
case 'Arial':
|
||||
// value 7 was found via interpolation by inspecting real Excel files with Arial 10 font.
|
||||
$columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText));
|
||||
$columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size
|
||||
break;
|
||||
|
||||
case 'Verdana':
|
||||
// value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font.
|
||||
$columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText));
|
||||
$columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size
|
||||
break;
|
||||
|
||||
default:
|
||||
// just assume Calibri
|
||||
$columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText));
|
||||
$columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate approximate rotated column width
|
||||
if ($rotation !== 0) {
|
||||
if ($rotation == -165) {
|
||||
// stacked text
|
||||
$columnWidth = 4; // approximation
|
||||
} else {
|
||||
// rotated text
|
||||
$columnWidth = $columnWidth * cos(deg2rad($rotation))
|
||||
+ $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation
|
||||
}
|
||||
}
|
||||
|
||||
// pixel width is an integer
|
||||
$columnWidth = (int) $columnWidth;
|
||||
return $columnWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate an (approximate) pixel size, based on a font points size
|
||||
*
|
||||
* @param int $fontSizeInPoints Font size (in points)
|
||||
* @return int Font size (in pixels)
|
||||
*/
|
||||
public static function fontSizeToPixels($fontSizeInPoints = 11) {
|
||||
return (int) ((4 / 3) * $fontSizeInPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate an (approximate) pixel size, based on inch size
|
||||
*
|
||||
* @param int $sizeInInch Font size (in inch)
|
||||
* @return int Size (in pixels)
|
||||
*/
|
||||
public static function inchSizeToPixels($sizeInInch = 1) {
|
||||
return ($sizeInInch * 96);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate an (approximate) pixel size, based on centimeter size
|
||||
*
|
||||
* @param int $sizeInCm Font size (in centimeters)
|
||||
* @return int Size (in pixels)
|
||||
*/
|
||||
public static function centimeterSizeToPixels($sizeInCm = 1) {
|
||||
return ($sizeInCm * 37.795275591);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the font path given the font
|
||||
*
|
||||
* @param PHPExcel_Style_Font
|
||||
* @return string Path to TrueType font file
|
||||
*/
|
||||
public static function getTrueTypeFontFileFromFont($font) {
|
||||
if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) {
|
||||
throw new PHPExcel_Exception('Valid directory to TrueType Font files not specified');
|
||||
}
|
||||
|
||||
$name = $font->getName();
|
||||
$bold = $font->getBold();
|
||||
$italic = $font->getItalic();
|
||||
|
||||
// Check if we can map font to true type font file
|
||||
switch ($name) {
|
||||
case 'Arial':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD)
|
||||
: ($italic ? self::ARIAL_ITALIC : self::ARIAL)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Calibri':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD)
|
||||
: ($italic ? self::CALIBRI_ITALIC : self::CALIBRI)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Courier New':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD)
|
||||
: ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Comic Sans MS':
|
||||
$fontFile = (
|
||||
$bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Georgia':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD)
|
||||
: ($italic ? self::GEORGIA_ITALIC : self::GEORGIA)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Impact':
|
||||
$fontFile = self::IMPACT;
|
||||
break;
|
||||
|
||||
case 'Liberation Sans':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD)
|
||||
: ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Lucida Console':
|
||||
$fontFile = self::LUCIDA_CONSOLE;
|
||||
break;
|
||||
|
||||
case 'Lucida Sans Unicode':
|
||||
$fontFile = self::LUCIDA_SANS_UNICODE;
|
||||
break;
|
||||
|
||||
case 'Microsoft Sans Serif':
|
||||
$fontFile = self::MICROSOFT_SANS_SERIF;
|
||||
break;
|
||||
|
||||
case 'Palatino Linotype':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD)
|
||||
: ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Symbol':
|
||||
$fontFile = self::SYMBOL;
|
||||
break;
|
||||
|
||||
case 'Tahoma':
|
||||
$fontFile = (
|
||||
$bold ? self::TAHOMA_BOLD : self::TAHOMA
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Times New Roman':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD)
|
||||
: ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Trebuchet MS':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD)
|
||||
: ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Verdana':
|
||||
$fontFile = (
|
||||
$bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD)
|
||||
: ($italic ? self::VERDANA_ITALIC : self::VERDANA)
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file');
|
||||
break;
|
||||
}
|
||||
|
||||
$fontFile = self::$trueTypeFontPath . $fontFile;
|
||||
|
||||
// Check if file actually exists
|
||||
if (!file_exists($fontFile)) {
|
||||
throw New PHPExcel_Exception('TrueType Font file not found');
|
||||
}
|
||||
|
||||
return $fontFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the associated charset for the font name.
|
||||
*
|
||||
* @param string $name Font name
|
||||
* @return int Character set code
|
||||
*/
|
||||
public static function getCharsetFromFontName($name)
|
||||
{
|
||||
switch ($name) {
|
||||
// Add more cases. Check FONT records in real Excel files.
|
||||
case 'EucrosiaUPC': return self::CHARSET_ANSI_THAI;
|
||||
case 'Wingdings': return self::CHARSET_SYMBOL;
|
||||
case 'Wingdings 2': return self::CHARSET_SYMBOL;
|
||||
case 'Wingdings 3': return self::CHARSET_SYMBOL;
|
||||
default: return self::CHARSET_ANSI_LATIN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effective column width for columns without a column dimension or column with width -1
|
||||
* For example, for Calibri 11 this is 9.140625 (64 px)
|
||||
*
|
||||
* @param PHPExcel_Style_Font $font The workbooks default font
|
||||
* @param boolean $pPixels true = return column width in pixels, false = return in OOXML units
|
||||
* @return mixed Column width
|
||||
*/
|
||||
public static function getDefaultColumnWidthByFont(PHPExcel_Style_Font $font, $pPixels = false)
|
||||
{
|
||||
if (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) {
|
||||
// Exact width can be determined
|
||||
$columnWidth = $pPixels ?
|
||||
self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px']
|
||||
: self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width'];
|
||||
|
||||
} else {
|
||||
// We don't have data for this particular font and size, use approximation by
|
||||
// extrapolating from Calibri 11
|
||||
$columnWidth = $pPixels ?
|
||||
self::$defaultColumnWidths['Calibri'][11]['px']
|
||||
: self::$defaultColumnWidths['Calibri'][11]['width'];
|
||||
$columnWidth = $columnWidth * $font->getSize() / 11;
|
||||
|
||||
// Round pixels to closest integer
|
||||
if ($pPixels) {
|
||||
$columnWidth = (int) round($columnWidth);
|
||||
}
|
||||
}
|
||||
|
||||
return $columnWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effective row height for rows without a row dimension or rows with height -1
|
||||
* For example, for Calibri 11 this is 15 points
|
||||
*
|
||||
* @param PHPExcel_Style_Font $font The workbooks default font
|
||||
* @return float Row height in points
|
||||
*/
|
||||
public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font)
|
||||
{
|
||||
switch ($font->getName()) {
|
||||
case 'Arial':
|
||||
switch ($font->getSize()) {
|
||||
case 10:
|
||||
// inspection of Arial 10 workbook says 12.75pt ~17px
|
||||
$rowHeight = 12.75;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// inspection of Arial 9 workbook says 12.00pt ~16px
|
||||
$rowHeight = 12;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// inspection of Arial 8 workbook says 11.25pt ~15px
|
||||
$rowHeight = 11.25;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// inspection of Arial 7 workbook says 9.00pt ~12px
|
||||
$rowHeight = 9;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 5:
|
||||
// inspection of Arial 5,6 workbook says 8.25pt ~11px
|
||||
$rowHeight = 8.25;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// inspection of Arial 4 workbook says 6.75pt ~9px
|
||||
$rowHeight = 6.75;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// inspection of Arial 3 workbook says 6.00pt ~8px
|
||||
$rowHeight = 6;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
// inspection of Arial 1,2 workbook says 5.25pt ~7px
|
||||
$rowHeight = 5.25;
|
||||
break;
|
||||
|
||||
default:
|
||||
// use Arial 10 workbook as an approximation, extrapolation
|
||||
$rowHeight = 12.75 * $font->getSize() / 10;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Calibri':
|
||||
switch ($font->getSize()) {
|
||||
case 11:
|
||||
// inspection of Calibri 11 workbook says 15.00pt ~20px
|
||||
$rowHeight = 15;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
// inspection of Calibri 10 workbook says 12.75pt ~17px
|
||||
$rowHeight = 12.75;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// inspection of Calibri 9 workbook says 12.00pt ~16px
|
||||
$rowHeight = 12;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// inspection of Calibri 8 workbook says 11.25pt ~15px
|
||||
$rowHeight = 11.25;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// inspection of Calibri 7 workbook says 9.00pt ~12px
|
||||
$rowHeight = 9;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 5:
|
||||
// inspection of Calibri 5,6 workbook says 8.25pt ~11px
|
||||
$rowHeight = 8.25;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// inspection of Calibri 4 workbook says 6.75pt ~9px
|
||||
$rowHeight = 6.75;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// inspection of Calibri 3 workbook says 6.00pt ~8px
|
||||
$rowHeight = 6.00;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
// inspection of Calibri 1,2 workbook says 5.25pt ~7px
|
||||
$rowHeight = 5.25;
|
||||
break;
|
||||
|
||||
default:
|
||||
// use Calibri 11 workbook as an approximation, extrapolation
|
||||
$rowHeight = 15 * $font->getSize() / 11;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Verdana':
|
||||
switch ($font->getSize()) {
|
||||
case 10:
|
||||
// inspection of Verdana 10 workbook says 12.75pt ~17px
|
||||
$rowHeight = 12.75;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// inspection of Verdana 9 workbook says 11.25pt ~15px
|
||||
$rowHeight = 11.25;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// inspection of Verdana 8 workbook says 10.50pt ~14px
|
||||
$rowHeight = 10.50;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// inspection of Verdana 7 workbook says 9.00pt ~12px
|
||||
$rowHeight = 9.00;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case 5:
|
||||
// inspection of Verdana 5,6 workbook says 8.25pt ~11px
|
||||
$rowHeight = 8.25;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// inspection of Verdana 4 workbook says 6.75pt ~9px
|
||||
$rowHeight = 6.75;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// inspection of Verdana 3 workbook says 6.00pt ~8px
|
||||
$rowHeight = 6;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 1:
|
||||
// inspection of Verdana 1,2 workbook says 5.25pt ~7px
|
||||
$rowHeight = 5.25;
|
||||
break;
|
||||
|
||||
default:
|
||||
// use Verdana 10 workbook as an approximation, extrapolation
|
||||
$rowHeight = 12.75 * $font->getSize() / 10;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// just use Calibri as an approximation
|
||||
$rowHeight = 15 * $font->getSize() / 11;
|
||||
break;
|
||||
}
|
||||
|
||||
return $rowHeight;
|
||||
}
|
||||
|
||||
}
|
16
extend/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT
Executable file
16
extend/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT
Executable file
@ -0,0 +1,16 @@
|
||||
Mar 1, 2005 11:15 AST by PM
|
||||
|
||||
+ For consistency, renamed Math.php to Maths.java, utils to util,
|
||||
tests to test, docs to doc -
|
||||
|
||||
+ Removed conditional logic from top of Matrix class.
|
||||
|
||||
+ Switched to using hypo function in Maths.php for all php-hypot calls.
|
||||
NOTE TO SELF: Need to make sure that all decompositions have been
|
||||
switched over to using the bundled hypo.
|
||||
|
||||
Feb 25, 2005 at 10:00 AST by PM
|
||||
|
||||
+ Recommend using simpler Error.php instead of JAMA_Error.php but
|
||||
can be persuaded otherwise.
|
||||
|
149
extend/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php
Executable file
149
extend/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php
Executable file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* @package JAMA
|
||||
*
|
||||
* Cholesky decomposition class
|
||||
*
|
||||
* For a symmetric, positive definite matrix A, the Cholesky decomposition
|
||||
* is an lower triangular matrix L so that A = L*L'.
|
||||
*
|
||||
* If the matrix is not symmetric or positive definite, the constructor
|
||||
* returns a partial decomposition and sets an internal flag that may
|
||||
* be queried by the isSPD() method.
|
||||
*
|
||||
* @author Paul Meagher
|
||||
* @author Michael Bommarito
|
||||
* @version 1.2
|
||||
*/
|
||||
class CholeskyDecomposition {
|
||||
|
||||
/**
|
||||
* Decomposition storage
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private $L = array();
|
||||
|
||||
/**
|
||||
* Matrix row and column dimension
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
private $m;
|
||||
|
||||
/**
|
||||
* Symmetric positive definite flag
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
private $isspd = true;
|
||||
|
||||
|
||||
/**
|
||||
* CholeskyDecomposition
|
||||
*
|
||||
* Class constructor - decomposes symmetric positive definite matrix
|
||||
* @param mixed Matrix square symmetric positive definite matrix
|
||||
*/
|
||||
public function __construct($A = null) {
|
||||
if ($A instanceof Matrix) {
|
||||
$this->L = $A->getArray();
|
||||
$this->m = $A->getRowDimension();
|
||||
|
||||
for($i = 0; $i < $this->m; ++$i) {
|
||||
for($j = $i; $j < $this->m; ++$j) {
|
||||
for($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) {
|
||||
$sum -= $this->L[$i][$k] * $this->L[$j][$k];
|
||||
}
|
||||
if ($i == $j) {
|
||||
if ($sum >= 0) {
|
||||
$this->L[$i][$i] = sqrt($sum);
|
||||
} else {
|
||||
$this->isspd = false;
|
||||
}
|
||||
} else {
|
||||
if ($this->L[$i][$i] != 0) {
|
||||
$this->L[$j][$i] = $sum / $this->L[$i][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ($k = $i+1; $k < $this->m; ++$k) {
|
||||
$this->L[$i][$k] = 0.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException));
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
|
||||
/**
|
||||
* Is the matrix symmetric and positive definite?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSPD() {
|
||||
return $this->isspd;
|
||||
} // function isSPD()
|
||||
|
||||
|
||||
/**
|
||||
* getL
|
||||
*
|
||||
* Return triangular factor.
|
||||
* @return Matrix Lower triangular matrix
|
||||
*/
|
||||
public function getL() {
|
||||
return new Matrix($this->L);
|
||||
} // function getL()
|
||||
|
||||
|
||||
/**
|
||||
* Solve A*X = B
|
||||
*
|
||||
* @param $B Row-equal matrix
|
||||
* @return Matrix L * L' * X = B
|
||||
*/
|
||||
public function solve($B = null) {
|
||||
if ($B instanceof Matrix) {
|
||||
if ($B->getRowDimension() == $this->m) {
|
||||
if ($this->isspd) {
|
||||
$X = $B->getArrayCopy();
|
||||
$nx = $B->getColumnDimension();
|
||||
|
||||
for ($k = 0; $k < $this->m; ++$k) {
|
||||
for ($i = $k + 1; $i < $this->m; ++$i) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k];
|
||||
}
|
||||
}
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$k][$j] /= $this->L[$k][$k];
|
||||
}
|
||||
}
|
||||
|
||||
for ($k = $this->m - 1; $k >= 0; --$k) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$k][$j] /= $this->L[$k][$k];
|
||||
}
|
||||
for ($i = 0; $i < $k; ++$i) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix($X, $this->m, $nx);
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(JAMAError(MatrixSPDException));
|
||||
}
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionException));
|
||||
}
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException));
|
||||
}
|
||||
} // function solve()
|
||||
|
||||
} // class CholeskyDecomposition
|
862
extend/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php
Executable file
862
extend/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php
Executable file
@ -0,0 +1,862 @@
|
||||
<?php
|
||||
/**
|
||||
* @package JAMA
|
||||
*
|
||||
* Class to obtain eigenvalues and eigenvectors of a real matrix.
|
||||
*
|
||||
* If A is symmetric, then A = V*D*V' where the eigenvalue matrix D
|
||||
* is diagonal and the eigenvector matrix V is orthogonal (i.e.
|
||||
* A = V.times(D.times(V.transpose())) and V.times(V.transpose())
|
||||
* equals the identity matrix).
|
||||
*
|
||||
* If A is not symmetric, then the eigenvalue matrix D is block diagonal
|
||||
* with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
|
||||
* lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The
|
||||
* columns of V represent the eigenvectors in the sense that A*V = V*D,
|
||||
* i.e. A.times(V) equals V.times(D). The matrix V may be badly
|
||||
* conditioned, or even singular, so the validity of the equation
|
||||
* A = V*D*inverse(V) depends upon V.cond().
|
||||
*
|
||||
* @author Paul Meagher
|
||||
* @license PHP v3.0
|
||||
* @version 1.1
|
||||
*/
|
||||
class EigenvalueDecomposition {
|
||||
|
||||
/**
|
||||
* Row and column dimension (square matrix).
|
||||
* @var int
|
||||
*/
|
||||
private $n;
|
||||
|
||||
/**
|
||||
* Internal symmetry flag.
|
||||
* @var int
|
||||
*/
|
||||
private $issymmetric;
|
||||
|
||||
/**
|
||||
* Arrays for internal storage of eigenvalues.
|
||||
* @var array
|
||||
*/
|
||||
private $d = array();
|
||||
private $e = array();
|
||||
|
||||
/**
|
||||
* Array for internal storage of eigenvectors.
|
||||
* @var array
|
||||
*/
|
||||
private $V = array();
|
||||
|
||||
/**
|
||||
* Array for internal storage of nonsymmetric Hessenberg form.
|
||||
* @var array
|
||||
*/
|
||||
private $H = array();
|
||||
|
||||
/**
|
||||
* Working storage for nonsymmetric algorithm.
|
||||
* @var array
|
||||
*/
|
||||
private $ort;
|
||||
|
||||
/**
|
||||
* Used for complex scalar division.
|
||||
* @var float
|
||||
*/
|
||||
private $cdivr;
|
||||
private $cdivi;
|
||||
|
||||
|
||||
/**
|
||||
* Symmetric Householder reduction to tridiagonal form.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function tred2 () {
|
||||
// This is derived from the Algol procedures tred2 by
|
||||
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
||||
// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
|
||||
// Fortran subroutine in EISPACK.
|
||||
$this->d = $this->V[$this->n-1];
|
||||
// Householder reduction to tridiagonal form.
|
||||
for ($i = $this->n-1; $i > 0; --$i) {
|
||||
$i_ = $i -1;
|
||||
// Scale to avoid under/overflow.
|
||||
$h = $scale = 0.0;
|
||||
$scale += array_sum(array_map(abs, $this->d));
|
||||
if ($scale == 0.0) {
|
||||
$this->e[$i] = $this->d[$i_];
|
||||
$this->d = array_slice($this->V[$i_], 0, $i_);
|
||||
for ($j = 0; $j < $i; ++$j) {
|
||||
$this->V[$j][$i] = $this->V[$i][$j] = 0.0;
|
||||
}
|
||||
} else {
|
||||
// Generate Householder vector.
|
||||
for ($k = 0; $k < $i; ++$k) {
|
||||
$this->d[$k] /= $scale;
|
||||
$h += pow($this->d[$k], 2);
|
||||
}
|
||||
$f = $this->d[$i_];
|
||||
$g = sqrt($h);
|
||||
if ($f > 0) {
|
||||
$g = -$g;
|
||||
}
|
||||
$this->e[$i] = $scale * $g;
|
||||
$h = $h - $f * $g;
|
||||
$this->d[$i_] = $f - $g;
|
||||
for ($j = 0; $j < $i; ++$j) {
|
||||
$this->e[$j] = 0.0;
|
||||
}
|
||||
// Apply similarity transformation to remaining columns.
|
||||
for ($j = 0; $j < $i; ++$j) {
|
||||
$f = $this->d[$j];
|
||||
$this->V[$j][$i] = $f;
|
||||
$g = $this->e[$j] + $this->V[$j][$j] * $f;
|
||||
for ($k = $j+1; $k <= $i_; ++$k) {
|
||||
$g += $this->V[$k][$j] * $this->d[$k];
|
||||
$this->e[$k] += $this->V[$k][$j] * $f;
|
||||
}
|
||||
$this->e[$j] = $g;
|
||||
}
|
||||
$f = 0.0;
|
||||
for ($j = 0; $j < $i; ++$j) {
|
||||
$this->e[$j] /= $h;
|
||||
$f += $this->e[$j] * $this->d[$j];
|
||||
}
|
||||
$hh = $f / (2 * $h);
|
||||
for ($j=0; $j < $i; ++$j) {
|
||||
$this->e[$j] -= $hh * $this->d[$j];
|
||||
}
|
||||
for ($j = 0; $j < $i; ++$j) {
|
||||
$f = $this->d[$j];
|
||||
$g = $this->e[$j];
|
||||
for ($k = $j; $k <= $i_; ++$k) {
|
||||
$this->V[$k][$j] -= ($f * $this->e[$k] + $g * $this->d[$k]);
|
||||
}
|
||||
$this->d[$j] = $this->V[$i-1][$j];
|
||||
$this->V[$i][$j] = 0.0;
|
||||
}
|
||||
}
|
||||
$this->d[$i] = $h;
|
||||
}
|
||||
|
||||
// Accumulate transformations.
|
||||
for ($i = 0; $i < $this->n-1; ++$i) {
|
||||
$this->V[$this->n-1][$i] = $this->V[$i][$i];
|
||||
$this->V[$i][$i] = 1.0;
|
||||
$h = $this->d[$i+1];
|
||||
if ($h != 0.0) {
|
||||
for ($k = 0; $k <= $i; ++$k) {
|
||||
$this->d[$k] = $this->V[$k][$i+1] / $h;
|
||||
}
|
||||
for ($j = 0; $j <= $i; ++$j) {
|
||||
$g = 0.0;
|
||||
for ($k = 0; $k <= $i; ++$k) {
|
||||
$g += $this->V[$k][$i+1] * $this->V[$k][$j];
|
||||
}
|
||||
for ($k = 0; $k <= $i; ++$k) {
|
||||
$this->V[$k][$j] -= $g * $this->d[$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
for ($k = 0; $k <= $i; ++$k) {
|
||||
$this->V[$k][$i+1] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
$this->d = $this->V[$this->n-1];
|
||||
$this->V[$this->n-1] = array_fill(0, $j, 0.0);
|
||||
$this->V[$this->n-1][$this->n-1] = 1.0;
|
||||
$this->e[0] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Symmetric tridiagonal QL algorithm.
|
||||
*
|
||||
* This is derived from the Algol procedures tql2, by
|
||||
* Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
||||
* Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
|
||||
* Fortran subroutine in EISPACK.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function tql2() {
|
||||
for ($i = 1; $i < $this->n; ++$i) {
|
||||
$this->e[$i-1] = $this->e[$i];
|
||||
}
|
||||
$this->e[$this->n-1] = 0.0;
|
||||
$f = 0.0;
|
||||
$tst1 = 0.0;
|
||||
$eps = pow(2.0,-52.0);
|
||||
|
||||
for ($l = 0; $l < $this->n; ++$l) {
|
||||
// Find small subdiagonal element
|
||||
$tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l]));
|
||||
$m = $l;
|
||||
while ($m < $this->n) {
|
||||
if (abs($this->e[$m]) <= $eps * $tst1)
|
||||
break;
|
||||
++$m;
|
||||
}
|
||||
// If m == l, $this->d[l] is an eigenvalue,
|
||||
// otherwise, iterate.
|
||||
if ($m > $l) {
|
||||
$iter = 0;
|
||||
do {
|
||||
// Could check iteration count here.
|
||||
$iter += 1;
|
||||
// Compute implicit shift
|
||||
$g = $this->d[$l];
|
||||
$p = ($this->d[$l+1] - $g) / (2.0 * $this->e[$l]);
|
||||
$r = hypo($p, 1.0);
|
||||
if ($p < 0)
|
||||
$r *= -1;
|
||||
$this->d[$l] = $this->e[$l] / ($p + $r);
|
||||
$this->d[$l+1] = $this->e[$l] * ($p + $r);
|
||||
$dl1 = $this->d[$l+1];
|
||||
$h = $g - $this->d[$l];
|
||||
for ($i = $l + 2; $i < $this->n; ++$i)
|
||||
$this->d[$i] -= $h;
|
||||
$f += $h;
|
||||
// Implicit QL transformation.
|
||||
$p = $this->d[$m];
|
||||
$c = 1.0;
|
||||
$c2 = $c3 = $c;
|
||||
$el1 = $this->e[$l + 1];
|
||||
$s = $s2 = 0.0;
|
||||
for ($i = $m-1; $i >= $l; --$i) {
|
||||
$c3 = $c2;
|
||||
$c2 = $c;
|
||||
$s2 = $s;
|
||||
$g = $c * $this->e[$i];
|
||||
$h = $c * $p;
|
||||
$r = hypo($p, $this->e[$i]);
|
||||
$this->e[$i+1] = $s * $r;
|
||||
$s = $this->e[$i] / $r;
|
||||
$c = $p / $r;
|
||||
$p = $c * $this->d[$i] - $s * $g;
|
||||
$this->d[$i+1] = $h + $s * ($c * $g + $s * $this->d[$i]);
|
||||
// Accumulate transformation.
|
||||
for ($k = 0; $k < $this->n; ++$k) {
|
||||
$h = $this->V[$k][$i+1];
|
||||
$this->V[$k][$i+1] = $s * $this->V[$k][$i] + $c * $h;
|
||||
$this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h;
|
||||
}
|
||||
}
|
||||
$p = -$s * $s2 * $c3 * $el1 * $this->e[$l] / $dl1;
|
||||
$this->e[$l] = $s * $p;
|
||||
$this->d[$l] = $c * $p;
|
||||
// Check for convergence.
|
||||
} while (abs($this->e[$l]) > $eps * $tst1);
|
||||
}
|
||||
$this->d[$l] = $this->d[$l] + $f;
|
||||
$this->e[$l] = 0.0;
|
||||
}
|
||||
|
||||
// Sort eigenvalues and corresponding vectors.
|
||||
for ($i = 0; $i < $this->n - 1; ++$i) {
|
||||
$k = $i;
|
||||
$p = $this->d[$i];
|
||||
for ($j = $i+1; $j < $this->n; ++$j) {
|
||||
if ($this->d[$j] < $p) {
|
||||
$k = $j;
|
||||
$p = $this->d[$j];
|
||||
}
|
||||
}
|
||||
if ($k != $i) {
|
||||
$this->d[$k] = $this->d[$i];
|
||||
$this->d[$i] = $p;
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
$p = $this->V[$j][$i];
|
||||
$this->V[$j][$i] = $this->V[$j][$k];
|
||||
$this->V[$j][$k] = $p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Nonsymmetric reduction to Hessenberg form.
|
||||
*
|
||||
* This is derived from the Algol procedures orthes and ortran,
|
||||
* by Martin and Wilkinson, Handbook for Auto. Comp.,
|
||||
* Vol.ii-Linear Algebra, and the corresponding
|
||||
* Fortran subroutines in EISPACK.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function orthes () {
|
||||
$low = 0;
|
||||
$high = $this->n-1;
|
||||
|
||||
for ($m = $low+1; $m <= $high-1; ++$m) {
|
||||
// Scale column.
|
||||
$scale = 0.0;
|
||||
for ($i = $m; $i <= $high; ++$i) {
|
||||
$scale = $scale + abs($this->H[$i][$m-1]);
|
||||
}
|
||||
if ($scale != 0.0) {
|
||||
// Compute Householder transformation.
|
||||
$h = 0.0;
|
||||
for ($i = $high; $i >= $m; --$i) {
|
||||
$this->ort[$i] = $this->H[$i][$m-1] / $scale;
|
||||
$h += $this->ort[$i] * $this->ort[$i];
|
||||
}
|
||||
$g = sqrt($h);
|
||||
if ($this->ort[$m] > 0) {
|
||||
$g *= -1;
|
||||
}
|
||||
$h -= $this->ort[$m] * $g;
|
||||
$this->ort[$m] -= $g;
|
||||
// Apply Householder similarity transformation
|
||||
// H = (I -u * u' / h) * H * (I -u * u') / h)
|
||||
for ($j = $m; $j < $this->n; ++$j) {
|
||||
$f = 0.0;
|
||||
for ($i = $high; $i >= $m; --$i) {
|
||||
$f += $this->ort[$i] * $this->H[$i][$j];
|
||||
}
|
||||
$f /= $h;
|
||||
for ($i = $m; $i <= $high; ++$i) {
|
||||
$this->H[$i][$j] -= $f * $this->ort[$i];
|
||||
}
|
||||
}
|
||||
for ($i = 0; $i <= $high; ++$i) {
|
||||
$f = 0.0;
|
||||
for ($j = $high; $j >= $m; --$j) {
|
||||
$f += $this->ort[$j] * $this->H[$i][$j];
|
||||
}
|
||||
$f = $f / $h;
|
||||
for ($j = $m; $j <= $high; ++$j) {
|
||||
$this->H[$i][$j] -= $f * $this->ort[$j];
|
||||
}
|
||||
}
|
||||
$this->ort[$m] = $scale * $this->ort[$m];
|
||||
$this->H[$m][$m-1] = $scale * $g;
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate transformations (Algol's ortran).
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
$this->V[$i][$j] = ($i == $j ? 1.0 : 0.0);
|
||||
}
|
||||
}
|
||||
for ($m = $high-1; $m >= $low+1; --$m) {
|
||||
if ($this->H[$m][$m-1] != 0.0) {
|
||||
for ($i = $m+1; $i <= $high; ++$i) {
|
||||
$this->ort[$i] = $this->H[$i][$m-1];
|
||||
}
|
||||
for ($j = $m; $j <= $high; ++$j) {
|
||||
$g = 0.0;
|
||||
for ($i = $m; $i <= $high; ++$i) {
|
||||
$g += $this->ort[$i] * $this->V[$i][$j];
|
||||
}
|
||||
// Double division avoids possible underflow
|
||||
$g = ($g / $this->ort[$m]) / $this->H[$m][$m-1];
|
||||
for ($i = $m; $i <= $high; ++$i) {
|
||||
$this->V[$i][$j] += $g * $this->ort[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs complex division.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function cdiv($xr, $xi, $yr, $yi) {
|
||||
if (abs($yr) > abs($yi)) {
|
||||
$r = $yi / $yr;
|
||||
$d = $yr + $r * $yi;
|
||||
$this->cdivr = ($xr + $r * $xi) / $d;
|
||||
$this->cdivi = ($xi - $r * $xr) / $d;
|
||||
} else {
|
||||
$r = $yr / $yi;
|
||||
$d = $yi + $r * $yr;
|
||||
$this->cdivr = ($r * $xr + $xi) / $d;
|
||||
$this->cdivi = ($r * $xi - $xr) / $d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Nonsymmetric reduction from Hessenberg to real Schur form.
|
||||
*
|
||||
* Code is derived from the Algol procedure hqr2,
|
||||
* by Martin and Wilkinson, Handbook for Auto. Comp.,
|
||||
* Vol.ii-Linear Algebra, and the corresponding
|
||||
* Fortran subroutine in EISPACK.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function hqr2 () {
|
||||
// Initialize
|
||||
$nn = $this->n;
|
||||
$n = $nn - 1;
|
||||
$low = 0;
|
||||
$high = $nn - 1;
|
||||
$eps = pow(2.0, -52.0);
|
||||
$exshift = 0.0;
|
||||
$p = $q = $r = $s = $z = 0;
|
||||
// Store roots isolated by balanc and compute matrix norm
|
||||
$norm = 0.0;
|
||||
|
||||
for ($i = 0; $i < $nn; ++$i) {
|
||||
if (($i < $low) OR ($i > $high)) {
|
||||
$this->d[$i] = $this->H[$i][$i];
|
||||
$this->e[$i] = 0.0;
|
||||
}
|
||||
for ($j = max($i-1, 0); $j < $nn; ++$j) {
|
||||
$norm = $norm + abs($this->H[$i][$j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Outer loop over eigenvalue index
|
||||
$iter = 0;
|
||||
while ($n >= $low) {
|
||||
// Look for single small sub-diagonal element
|
||||
$l = $n;
|
||||
while ($l > $low) {
|
||||
$s = abs($this->H[$l-1][$l-1]) + abs($this->H[$l][$l]);
|
||||
if ($s == 0.0) {
|
||||
$s = $norm;
|
||||
}
|
||||
if (abs($this->H[$l][$l-1]) < $eps * $s) {
|
||||
break;
|
||||
}
|
||||
--$l;
|
||||
}
|
||||
// Check for convergence
|
||||
// One root found
|
||||
if ($l == $n) {
|
||||
$this->H[$n][$n] = $this->H[$n][$n] + $exshift;
|
||||
$this->d[$n] = $this->H[$n][$n];
|
||||
$this->e[$n] = 0.0;
|
||||
--$n;
|
||||
$iter = 0;
|
||||
// Two roots found
|
||||
} else if ($l == $n-1) {
|
||||
$w = $this->H[$n][$n-1] * $this->H[$n-1][$n];
|
||||
$p = ($this->H[$n-1][$n-1] - $this->H[$n][$n]) / 2.0;
|
||||
$q = $p * $p + $w;
|
||||
$z = sqrt(abs($q));
|
||||
$this->H[$n][$n] = $this->H[$n][$n] + $exshift;
|
||||
$this->H[$n-1][$n-1] = $this->H[$n-1][$n-1] + $exshift;
|
||||
$x = $this->H[$n][$n];
|
||||
// Real pair
|
||||
if ($q >= 0) {
|
||||
if ($p >= 0) {
|
||||
$z = $p + $z;
|
||||
} else {
|
||||
$z = $p - $z;
|
||||
}
|
||||
$this->d[$n-1] = $x + $z;
|
||||
$this->d[$n] = $this->d[$n-1];
|
||||
if ($z != 0.0) {
|
||||
$this->d[$n] = $x - $w / $z;
|
||||
}
|
||||
$this->e[$n-1] = 0.0;
|
||||
$this->e[$n] = 0.0;
|
||||
$x = $this->H[$n][$n-1];
|
||||
$s = abs($x) + abs($z);
|
||||
$p = $x / $s;
|
||||
$q = $z / $s;
|
||||
$r = sqrt($p * $p + $q * $q);
|
||||
$p = $p / $r;
|
||||
$q = $q / $r;
|
||||
// Row modification
|
||||
for ($j = $n-1; $j < $nn; ++$j) {
|
||||
$z = $this->H[$n-1][$j];
|
||||
$this->H[$n-1][$j] = $q * $z + $p * $this->H[$n][$j];
|
||||
$this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z;
|
||||
}
|
||||
// Column modification
|
||||
for ($i = 0; $i <= n; ++$i) {
|
||||
$z = $this->H[$i][$n-1];
|
||||
$this->H[$i][$n-1] = $q * $z + $p * $this->H[$i][$n];
|
||||
$this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z;
|
||||
}
|
||||
// Accumulate transformations
|
||||
for ($i = $low; $i <= $high; ++$i) {
|
||||
$z = $this->V[$i][$n-1];
|
||||
$this->V[$i][$n-1] = $q * $z + $p * $this->V[$i][$n];
|
||||
$this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z;
|
||||
}
|
||||
// Complex pair
|
||||
} else {
|
||||
$this->d[$n-1] = $x + $p;
|
||||
$this->d[$n] = $x + $p;
|
||||
$this->e[$n-1] = $z;
|
||||
$this->e[$n] = -$z;
|
||||
}
|
||||
$n = $n - 2;
|
||||
$iter = 0;
|
||||
// No convergence yet
|
||||
} else {
|
||||
// Form shift
|
||||
$x = $this->H[$n][$n];
|
||||
$y = 0.0;
|
||||
$w = 0.0;
|
||||
if ($l < $n) {
|
||||
$y = $this->H[$n-1][$n-1];
|
||||
$w = $this->H[$n][$n-1] * $this->H[$n-1][$n];
|
||||
}
|
||||
// Wilkinson's original ad hoc shift
|
||||
if ($iter == 10) {
|
||||
$exshift += $x;
|
||||
for ($i = $low; $i <= $n; ++$i) {
|
||||
$this->H[$i][$i] -= $x;
|
||||
}
|
||||
$s = abs($this->H[$n][$n-1]) + abs($this->H[$n-1][$n-2]);
|
||||
$x = $y = 0.75 * $s;
|
||||
$w = -0.4375 * $s * $s;
|
||||
}
|
||||
// MATLAB's new ad hoc shift
|
||||
if ($iter == 30) {
|
||||
$s = ($y - $x) / 2.0;
|
||||
$s = $s * $s + $w;
|
||||
if ($s > 0) {
|
||||
$s = sqrt($s);
|
||||
if ($y < $x) {
|
||||
$s = -$s;
|
||||
}
|
||||
$s = $x - $w / (($y - $x) / 2.0 + $s);
|
||||
for ($i = $low; $i <= $n; ++$i) {
|
||||
$this->H[$i][$i] -= $s;
|
||||
}
|
||||
$exshift += $s;
|
||||
$x = $y = $w = 0.964;
|
||||
}
|
||||
}
|
||||
// Could check iteration count here.
|
||||
$iter = $iter + 1;
|
||||
// Look for two consecutive small sub-diagonal elements
|
||||
$m = $n - 2;
|
||||
while ($m >= $l) {
|
||||
$z = $this->H[$m][$m];
|
||||
$r = $x - $z;
|
||||
$s = $y - $z;
|
||||
$p = ($r * $s - $w) / $this->H[$m+1][$m] + $this->H[$m][$m+1];
|
||||
$q = $this->H[$m+1][$m+1] - $z - $r - $s;
|
||||
$r = $this->H[$m+2][$m+1];
|
||||
$s = abs($p) + abs($q) + abs($r);
|
||||
$p = $p / $s;
|
||||
$q = $q / $s;
|
||||
$r = $r / $s;
|
||||
if ($m == $l) {
|
||||
break;
|
||||
}
|
||||
if (abs($this->H[$m][$m-1]) * (abs($q) + abs($r)) <
|
||||
$eps * (abs($p) * (abs($this->H[$m-1][$m-1]) + abs($z) + abs($this->H[$m+1][$m+1])))) {
|
||||
break;
|
||||
}
|
||||
--$m;
|
||||
}
|
||||
for ($i = $m + 2; $i <= $n; ++$i) {
|
||||
$this->H[$i][$i-2] = 0.0;
|
||||
if ($i > $m+2) {
|
||||
$this->H[$i][$i-3] = 0.0;
|
||||
}
|
||||
}
|
||||
// Double QR step involving rows l:n and columns m:n
|
||||
for ($k = $m; $k <= $n-1; ++$k) {
|
||||
$notlast = ($k != $n-1);
|
||||
if ($k != $m) {
|
||||
$p = $this->H[$k][$k-1];
|
||||
$q = $this->H[$k+1][$k-1];
|
||||
$r = ($notlast ? $this->H[$k+2][$k-1] : 0.0);
|
||||
$x = abs($p) + abs($q) + abs($r);
|
||||
if ($x != 0.0) {
|
||||
$p = $p / $x;
|
||||
$q = $q / $x;
|
||||
$r = $r / $x;
|
||||
}
|
||||
}
|
||||
if ($x == 0.0) {
|
||||
break;
|
||||
}
|
||||
$s = sqrt($p * $p + $q * $q + $r * $r);
|
||||
if ($p < 0) {
|
||||
$s = -$s;
|
||||
}
|
||||
if ($s != 0) {
|
||||
if ($k != $m) {
|
||||
$this->H[$k][$k-1] = -$s * $x;
|
||||
} elseif ($l != $m) {
|
||||
$this->H[$k][$k-1] = -$this->H[$k][$k-1];
|
||||
}
|
||||
$p = $p + $s;
|
||||
$x = $p / $s;
|
||||
$y = $q / $s;
|
||||
$z = $r / $s;
|
||||
$q = $q / $p;
|
||||
$r = $r / $p;
|
||||
// Row modification
|
||||
for ($j = $k; $j < $nn; ++$j) {
|
||||
$p = $this->H[$k][$j] + $q * $this->H[$k+1][$j];
|
||||
if ($notlast) {
|
||||
$p = $p + $r * $this->H[$k+2][$j];
|
||||
$this->H[$k+2][$j] = $this->H[$k+2][$j] - $p * $z;
|
||||
}
|
||||
$this->H[$k][$j] = $this->H[$k][$j] - $p * $x;
|
||||
$this->H[$k+1][$j] = $this->H[$k+1][$j] - $p * $y;
|
||||
}
|
||||
// Column modification
|
||||
for ($i = 0; $i <= min($n, $k+3); ++$i) {
|
||||
$p = $x * $this->H[$i][$k] + $y * $this->H[$i][$k+1];
|
||||
if ($notlast) {
|
||||
$p = $p + $z * $this->H[$i][$k+2];
|
||||
$this->H[$i][$k+2] = $this->H[$i][$k+2] - $p * $r;
|
||||
}
|
||||
$this->H[$i][$k] = $this->H[$i][$k] - $p;
|
||||
$this->H[$i][$k+1] = $this->H[$i][$k+1] - $p * $q;
|
||||
}
|
||||
// Accumulate transformations
|
||||
for ($i = $low; $i <= $high; ++$i) {
|
||||
$p = $x * $this->V[$i][$k] + $y * $this->V[$i][$k+1];
|
||||
if ($notlast) {
|
||||
$p = $p + $z * $this->V[$i][$k+2];
|
||||
$this->V[$i][$k+2] = $this->V[$i][$k+2] - $p * $r;
|
||||
}
|
||||
$this->V[$i][$k] = $this->V[$i][$k] - $p;
|
||||
$this->V[$i][$k+1] = $this->V[$i][$k+1] - $p * $q;
|
||||
}
|
||||
} // ($s != 0)
|
||||
} // k loop
|
||||
} // check convergence
|
||||
} // while ($n >= $low)
|
||||
|
||||
// Backsubstitute to find vectors of upper triangular form
|
||||
if ($norm == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ($n = $nn-1; $n >= 0; --$n) {
|
||||
$p = $this->d[$n];
|
||||
$q = $this->e[$n];
|
||||
// Real vector
|
||||
if ($q == 0) {
|
||||
$l = $n;
|
||||
$this->H[$n][$n] = 1.0;
|
||||
for ($i = $n-1; $i >= 0; --$i) {
|
||||
$w = $this->H[$i][$i] - $p;
|
||||
$r = 0.0;
|
||||
for ($j = $l; $j <= $n; ++$j) {
|
||||
$r = $r + $this->H[$i][$j] * $this->H[$j][$n];
|
||||
}
|
||||
if ($this->e[$i] < 0.0) {
|
||||
$z = $w;
|
||||
$s = $r;
|
||||
} else {
|
||||
$l = $i;
|
||||
if ($this->e[$i] == 0.0) {
|
||||
if ($w != 0.0) {
|
||||
$this->H[$i][$n] = -$r / $w;
|
||||
} else {
|
||||
$this->H[$i][$n] = -$r / ($eps * $norm);
|
||||
}
|
||||
// Solve real equations
|
||||
} else {
|
||||
$x = $this->H[$i][$i+1];
|
||||
$y = $this->H[$i+1][$i];
|
||||
$q = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i];
|
||||
$t = ($x * $s - $z * $r) / $q;
|
||||
$this->H[$i][$n] = $t;
|
||||
if (abs($x) > abs($z)) {
|
||||
$this->H[$i+1][$n] = (-$r - $w * $t) / $x;
|
||||
} else {
|
||||
$this->H[$i+1][$n] = (-$s - $y * $t) / $z;
|
||||
}
|
||||
}
|
||||
// Overflow control
|
||||
$t = abs($this->H[$i][$n]);
|
||||
if (($eps * $t) * $t > 1) {
|
||||
for ($j = $i; $j <= $n; ++$j) {
|
||||
$this->H[$j][$n] = $this->H[$j][$n] / $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Complex vector
|
||||
} else if ($q < 0) {
|
||||
$l = $n-1;
|
||||
// Last vector component imaginary so matrix is triangular
|
||||
if (abs($this->H[$n][$n-1]) > abs($this->H[$n-1][$n])) {
|
||||
$this->H[$n-1][$n-1] = $q / $this->H[$n][$n-1];
|
||||
$this->H[$n-1][$n] = -($this->H[$n][$n] - $p) / $this->H[$n][$n-1];
|
||||
} else {
|
||||
$this->cdiv(0.0, -$this->H[$n-1][$n], $this->H[$n-1][$n-1] - $p, $q);
|
||||
$this->H[$n-1][$n-1] = $this->cdivr;
|
||||
$this->H[$n-1][$n] = $this->cdivi;
|
||||
}
|
||||
$this->H[$n][$n-1] = 0.0;
|
||||
$this->H[$n][$n] = 1.0;
|
||||
for ($i = $n-2; $i >= 0; --$i) {
|
||||
// double ra,sa,vr,vi;
|
||||
$ra = 0.0;
|
||||
$sa = 0.0;
|
||||
for ($j = $l; $j <= $n; ++$j) {
|
||||
$ra = $ra + $this->H[$i][$j] * $this->H[$j][$n-1];
|
||||
$sa = $sa + $this->H[$i][$j] * $this->H[$j][$n];
|
||||
}
|
||||
$w = $this->H[$i][$i] - $p;
|
||||
if ($this->e[$i] < 0.0) {
|
||||
$z = $w;
|
||||
$r = $ra;
|
||||
$s = $sa;
|
||||
} else {
|
||||
$l = $i;
|
||||
if ($this->e[$i] == 0) {
|
||||
$this->cdiv(-$ra, -$sa, $w, $q);
|
||||
$this->H[$i][$n-1] = $this->cdivr;
|
||||
$this->H[$i][$n] = $this->cdivi;
|
||||
} else {
|
||||
// Solve complex equations
|
||||
$x = $this->H[$i][$i+1];
|
||||
$y = $this->H[$i+1][$i];
|
||||
$vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q;
|
||||
$vi = ($this->d[$i] - $p) * 2.0 * $q;
|
||||
if ($vr == 0.0 & $vi == 0.0) {
|
||||
$vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z));
|
||||
}
|
||||
$this->cdiv($x * $r - $z * $ra + $q * $sa, $x * $s - $z * $sa - $q * $ra, $vr, $vi);
|
||||
$this->H[$i][$n-1] = $this->cdivr;
|
||||
$this->H[$i][$n] = $this->cdivi;
|
||||
if (abs($x) > (abs($z) + abs($q))) {
|
||||
$this->H[$i+1][$n-1] = (-$ra - $w * $this->H[$i][$n-1] + $q * $this->H[$i][$n]) / $x;
|
||||
$this->H[$i+1][$n] = (-$sa - $w * $this->H[$i][$n] - $q * $this->H[$i][$n-1]) / $x;
|
||||
} else {
|
||||
$this->cdiv(-$r - $y * $this->H[$i][$n-1], -$s - $y * $this->H[$i][$n], $z, $q);
|
||||
$this->H[$i+1][$n-1] = $this->cdivr;
|
||||
$this->H[$i+1][$n] = $this->cdivi;
|
||||
}
|
||||
}
|
||||
// Overflow control
|
||||
$t = max(abs($this->H[$i][$n-1]),abs($this->H[$i][$n]));
|
||||
if (($eps * $t) * $t > 1) {
|
||||
for ($j = $i; $j <= $n; ++$j) {
|
||||
$this->H[$j][$n-1] = $this->H[$j][$n-1] / $t;
|
||||
$this->H[$j][$n] = $this->H[$j][$n] / $t;
|
||||
}
|
||||
}
|
||||
} // end else
|
||||
} // end for
|
||||
} // end else for complex case
|
||||
} // end for
|
||||
|
||||
// Vectors of isolated roots
|
||||
for ($i = 0; $i < $nn; ++$i) {
|
||||
if ($i < $low | $i > $high) {
|
||||
for ($j = $i; $j < $nn; ++$j) {
|
||||
$this->V[$i][$j] = $this->H[$i][$j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Back transformation to get eigenvectors of original matrix
|
||||
for ($j = $nn-1; $j >= $low; --$j) {
|
||||
for ($i = $low; $i <= $high; ++$i) {
|
||||
$z = 0.0;
|
||||
for ($k = $low; $k <= min($j,$high); ++$k) {
|
||||
$z = $z + $this->V[$i][$k] * $this->H[$k][$j];
|
||||
}
|
||||
$this->V[$i][$j] = $z;
|
||||
}
|
||||
}
|
||||
} // end hqr2
|
||||
|
||||
|
||||
/**
|
||||
* Constructor: Check for symmetry, then construct the eigenvalue decomposition
|
||||
*
|
||||
* @access public
|
||||
* @param A Square matrix
|
||||
* @return Structure to access D and V.
|
||||
*/
|
||||
public function __construct($Arg) {
|
||||
$this->A = $Arg->getArray();
|
||||
$this->n = $Arg->getColumnDimension();
|
||||
|
||||
$issymmetric = true;
|
||||
for ($j = 0; ($j < $this->n) & $issymmetric; ++$j) {
|
||||
for ($i = 0; ($i < $this->n) & $issymmetric; ++$i) {
|
||||
$issymmetric = ($this->A[$i][$j] == $this->A[$j][$i]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($issymmetric) {
|
||||
$this->V = $this->A;
|
||||
// Tridiagonalize.
|
||||
$this->tred2();
|
||||
// Diagonalize.
|
||||
$this->tql2();
|
||||
} else {
|
||||
$this->H = $this->A;
|
||||
$this->ort = array();
|
||||
// Reduce to Hessenberg form.
|
||||
$this->orthes();
|
||||
// Reduce Hessenberg to real Schur form.
|
||||
$this->hqr2();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the eigenvector matrix
|
||||
*
|
||||
* @access public
|
||||
* @return V
|
||||
*/
|
||||
public function getV() {
|
||||
return new Matrix($this->V, $this->n, $this->n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the real parts of the eigenvalues
|
||||
*
|
||||
* @access public
|
||||
* @return real(diag(D))
|
||||
*/
|
||||
public function getRealEigenvalues() {
|
||||
return $this->d;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the imaginary parts of the eigenvalues
|
||||
*
|
||||
* @access public
|
||||
* @return imag(diag(D))
|
||||
*/
|
||||
public function getImagEigenvalues() {
|
||||
return $this->e;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the block diagonal eigenvalue matrix
|
||||
*
|
||||
* @access public
|
||||
* @return D
|
||||
*/
|
||||
public function getD() {
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
$D[$i] = array_fill(0, $this->n, 0.0);
|
||||
$D[$i][$i] = $this->d[$i];
|
||||
if ($this->e[$i] == 0) {
|
||||
continue;
|
||||
}
|
||||
$o = ($this->e[$i] > 0) ? $i + 1 : $i - 1;
|
||||
$D[$i][$o] = $this->e[$i];
|
||||
}
|
||||
return new Matrix($D);
|
||||
}
|
||||
|
||||
} // class EigenvalueDecomposition
|
258
extend/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php
Executable file
258
extend/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php
Executable file
@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* @package JAMA
|
||||
*
|
||||
* For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
|
||||
* unit lower triangular matrix L, an n-by-n upper triangular matrix U,
|
||||
* and a permutation vector piv of length m so that A(piv,:) = L*U.
|
||||
* If m < n, then L is m-by-m and U is m-by-n.
|
||||
*
|
||||
* The LU decompostion with pivoting always exists, even if the matrix is
|
||||
* singular, so the constructor will never fail. The primary use of the
|
||||
* LU decomposition is in the solution of square systems of simultaneous
|
||||
* linear equations. This will fail if isNonsingular() returns false.
|
||||
*
|
||||
* @author Paul Meagher
|
||||
* @author Bartosz Matosiuk
|
||||
* @author Michael Bommarito
|
||||
* @version 1.1
|
||||
* @license PHP v3.0
|
||||
*/
|
||||
class PHPExcel_Shared_JAMA_LUDecomposition {
|
||||
|
||||
const MatrixSingularException = "Can only perform operation on singular matrix.";
|
||||
const MatrixSquareException = "Mismatched Row dimension";
|
||||
|
||||
/**
|
||||
* Decomposition storage
|
||||
* @var array
|
||||
*/
|
||||
private $LU = array();
|
||||
|
||||
/**
|
||||
* Row dimension.
|
||||
* @var int
|
||||
*/
|
||||
private $m;
|
||||
|
||||
/**
|
||||
* Column dimension.
|
||||
* @var int
|
||||
*/
|
||||
private $n;
|
||||
|
||||
/**
|
||||
* Pivot sign.
|
||||
* @var int
|
||||
*/
|
||||
private $pivsign;
|
||||
|
||||
/**
|
||||
* Internal storage of pivot vector.
|
||||
* @var array
|
||||
*/
|
||||
private $piv = array();
|
||||
|
||||
|
||||
/**
|
||||
* LU Decomposition constructor.
|
||||
*
|
||||
* @param $A Rectangular matrix
|
||||
* @return Structure to access L, U and piv.
|
||||
*/
|
||||
public function __construct($A) {
|
||||
if ($A instanceof PHPExcel_Shared_JAMA_Matrix) {
|
||||
// Use a "left-looking", dot-product, Crout/Doolittle algorithm.
|
||||
$this->LU = $A->getArray();
|
||||
$this->m = $A->getRowDimension();
|
||||
$this->n = $A->getColumnDimension();
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$this->piv[$i] = $i;
|
||||
}
|
||||
$this->pivsign = 1;
|
||||
$LUrowi = $LUcolj = array();
|
||||
|
||||
// Outer loop.
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
// Make a copy of the j-th column to localize references.
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$LUcolj[$i] = &$this->LU[$i][$j];
|
||||
}
|
||||
// Apply previous transformations.
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$LUrowi = $this->LU[$i];
|
||||
// Most of the time is spent in the following dot product.
|
||||
$kmax = min($i,$j);
|
||||
$s = 0.0;
|
||||
for ($k = 0; $k < $kmax; ++$k) {
|
||||
$s += $LUrowi[$k] * $LUcolj[$k];
|
||||
}
|
||||
$LUrowi[$j] = $LUcolj[$i] -= $s;
|
||||
}
|
||||
// Find pivot and exchange if necessary.
|
||||
$p = $j;
|
||||
for ($i = $j+1; $i < $this->m; ++$i) {
|
||||
if (abs($LUcolj[$i]) > abs($LUcolj[$p])) {
|
||||
$p = $i;
|
||||
}
|
||||
}
|
||||
if ($p != $j) {
|
||||
for ($k = 0; $k < $this->n; ++$k) {
|
||||
$t = $this->LU[$p][$k];
|
||||
$this->LU[$p][$k] = $this->LU[$j][$k];
|
||||
$this->LU[$j][$k] = $t;
|
||||
}
|
||||
$k = $this->piv[$p];
|
||||
$this->piv[$p] = $this->piv[$j];
|
||||
$this->piv[$j] = $k;
|
||||
$this->pivsign = $this->pivsign * -1;
|
||||
}
|
||||
// Compute multipliers.
|
||||
if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) {
|
||||
for ($i = $j+1; $i < $this->m; ++$i) {
|
||||
$this->LU[$i][$j] /= $this->LU[$j][$j];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException);
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
|
||||
/**
|
||||
* Get lower triangular factor.
|
||||
*
|
||||
* @return array Lower triangular factor
|
||||
*/
|
||||
public function getL() {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
if ($i > $j) {
|
||||
$L[$i][$j] = $this->LU[$i][$j];
|
||||
} elseif ($i == $j) {
|
||||
$L[$i][$j] = 1.0;
|
||||
} else {
|
||||
$L[$i][$j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PHPExcel_Shared_JAMA_Matrix($L);
|
||||
} // function getL()
|
||||
|
||||
|
||||
/**
|
||||
* Get upper triangular factor.
|
||||
*
|
||||
* @return array Upper triangular factor
|
||||
*/
|
||||
public function getU() {
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
if ($i <= $j) {
|
||||
$U[$i][$j] = $this->LU[$i][$j];
|
||||
} else {
|
||||
$U[$i][$j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PHPExcel_Shared_JAMA_Matrix($U);
|
||||
} // function getU()
|
||||
|
||||
|
||||
/**
|
||||
* Return pivot permutation vector.
|
||||
*
|
||||
* @return array Pivot vector
|
||||
*/
|
||||
public function getPivot() {
|
||||
return $this->piv;
|
||||
} // function getPivot()
|
||||
|
||||
|
||||
/**
|
||||
* Alias for getPivot
|
||||
*
|
||||
* @see getPivot
|
||||
*/
|
||||
public function getDoublePivot() {
|
||||
return $this->getPivot();
|
||||
} // function getDoublePivot()
|
||||
|
||||
|
||||
/**
|
||||
* Is the matrix nonsingular?
|
||||
*
|
||||
* @return true if U, and hence A, is nonsingular.
|
||||
*/
|
||||
public function isNonsingular() {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
if ($this->LU[$j][$j] == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} // function isNonsingular()
|
||||
|
||||
|
||||
/**
|
||||
* Count determinants
|
||||
*
|
||||
* @return array d matrix deterninat
|
||||
*/
|
||||
public function det() {
|
||||
if ($this->m == $this->n) {
|
||||
$d = $this->pivsign;
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
$d *= $this->LU[$j][$j];
|
||||
}
|
||||
return $d;
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException);
|
||||
}
|
||||
} // function det()
|
||||
|
||||
|
||||
/**
|
||||
* Solve A*X = B
|
||||
*
|
||||
* @param $B A Matrix with as many rows as A and any number of columns.
|
||||
* @return X so that L*U*X = B(piv,:)
|
||||
* @PHPExcel_Calculation_Exception IllegalArgumentException Matrix row dimensions must agree.
|
||||
* @PHPExcel_Calculation_Exception RuntimeException Matrix is singular.
|
||||
*/
|
||||
public function solve($B) {
|
||||
if ($B->getRowDimension() == $this->m) {
|
||||
if ($this->isNonsingular()) {
|
||||
// Copy right hand side with pivoting
|
||||
$nx = $B->getColumnDimension();
|
||||
$X = $B->getMatrix($this->piv, 0, $nx-1);
|
||||
// Solve L*Y = B(piv,:)
|
||||
for ($k = 0; $k < $this->n; ++$k) {
|
||||
for ($i = $k+1; $i < $this->n; ++$i) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Solve U*X = Y;
|
||||
for ($k = $this->n-1; $k >= 0; --$k) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X->A[$k][$j] /= $this->LU[$k][$k];
|
||||
}
|
||||
for ($i = 0; $i < $k; ++$i) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $X;
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(self::MatrixSingularException);
|
||||
}
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(self::MatrixSquareException);
|
||||
}
|
||||
} // function solve()
|
||||
|
||||
} // class PHPExcel_Shared_JAMA_LUDecomposition
|
1059
extend/phpexcel/PHPExcel/Shared/JAMA/Matrix.php
Executable file
1059
extend/phpexcel/PHPExcel/Shared/JAMA/Matrix.php
Executable file
File diff suppressed because it is too large
Load Diff
234
extend/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php
Executable file
234
extend/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php
Executable file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* @package JAMA
|
||||
*
|
||||
* For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n
|
||||
* orthogonal matrix Q and an n-by-n upper triangular matrix R so that
|
||||
* A = Q*R.
|
||||
*
|
||||
* The QR decompostion always exists, even if the matrix does not have
|
||||
* full rank, so the constructor will never fail. The primary use of the
|
||||
* QR decomposition is in the least squares solution of nonsquare systems
|
||||
* of simultaneous linear equations. This will fail if isFullRank()
|
||||
* returns false.
|
||||
*
|
||||
* @author Paul Meagher
|
||||
* @license PHP v3.0
|
||||
* @version 1.1
|
||||
*/
|
||||
class PHPExcel_Shared_JAMA_QRDecomposition {
|
||||
|
||||
const MatrixRankException = "Can only perform operation on full-rank matrix.";
|
||||
|
||||
/**
|
||||
* Array for internal storage of decomposition.
|
||||
* @var array
|
||||
*/
|
||||
private $QR = array();
|
||||
|
||||
/**
|
||||
* Row dimension.
|
||||
* @var integer
|
||||
*/
|
||||
private $m;
|
||||
|
||||
/**
|
||||
* Column dimension.
|
||||
* @var integer
|
||||
*/
|
||||
private $n;
|
||||
|
||||
/**
|
||||
* Array for internal storage of diagonal of R.
|
||||
* @var array
|
||||
*/
|
||||
private $Rdiag = array();
|
||||
|
||||
|
||||
/**
|
||||
* QR Decomposition computed by Householder reflections.
|
||||
*
|
||||
* @param matrix $A Rectangular matrix
|
||||
* @return Structure to access R and the Householder vectors and compute Q.
|
||||
*/
|
||||
public function __construct($A) {
|
||||
if($A instanceof PHPExcel_Shared_JAMA_Matrix) {
|
||||
// Initialize.
|
||||
$this->QR = $A->getArrayCopy();
|
||||
$this->m = $A->getRowDimension();
|
||||
$this->n = $A->getColumnDimension();
|
||||
// Main loop.
|
||||
for ($k = 0; $k < $this->n; ++$k) {
|
||||
// Compute 2-norm of k-th column without under/overflow.
|
||||
$nrm = 0.0;
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$nrm = hypo($nrm, $this->QR[$i][$k]);
|
||||
}
|
||||
if ($nrm != 0.0) {
|
||||
// Form k-th Householder vector.
|
||||
if ($this->QR[$k][$k] < 0) {
|
||||
$nrm = -$nrm;
|
||||
}
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$this->QR[$i][$k] /= $nrm;
|
||||
}
|
||||
$this->QR[$k][$k] += 1.0;
|
||||
// Apply transformation to remaining columns.
|
||||
for ($j = $k+1; $j < $this->n; ++$j) {
|
||||
$s = 0.0;
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$s += $this->QR[$i][$k] * $this->QR[$i][$j];
|
||||
}
|
||||
$s = -$s/$this->QR[$k][$k];
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$this->QR[$i][$j] += $s * $this->QR[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->Rdiag[$k] = -$nrm;
|
||||
}
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException);
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
|
||||
/**
|
||||
* Is the matrix full rank?
|
||||
*
|
||||
* @return boolean true if R, and hence A, has full rank, else false.
|
||||
*/
|
||||
public function isFullRank() {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
if ($this->Rdiag[$j] == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} // function isFullRank()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Householder vectors
|
||||
*
|
||||
* @return Matrix Lower trapezoidal matrix whose columns define the reflections
|
||||
*/
|
||||
public function getH() {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
if ($i >= $j) {
|
||||
$H[$i][$j] = $this->QR[$i][$j];
|
||||
} else {
|
||||
$H[$i][$j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PHPExcel_Shared_JAMA_Matrix($H);
|
||||
} // function getH()
|
||||
|
||||
|
||||
/**
|
||||
* Return the upper triangular factor
|
||||
*
|
||||
* @return Matrix upper triangular factor
|
||||
*/
|
||||
public function getR() {
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
if ($i < $j) {
|
||||
$R[$i][$j] = $this->QR[$i][$j];
|
||||
} elseif ($i == $j) {
|
||||
$R[$i][$j] = $this->Rdiag[$i];
|
||||
} else {
|
||||
$R[$i][$j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PHPExcel_Shared_JAMA_Matrix($R);
|
||||
} // function getR()
|
||||
|
||||
|
||||
/**
|
||||
* Generate and return the (economy-sized) orthogonal factor
|
||||
*
|
||||
* @return Matrix orthogonal factor
|
||||
*/
|
||||
public function getQ() {
|
||||
for ($k = $this->n-1; $k >= 0; --$k) {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$Q[$i][$k] = 0.0;
|
||||
}
|
||||
$Q[$k][$k] = 1.0;
|
||||
for ($j = $k; $j < $this->n; ++$j) {
|
||||
if ($this->QR[$k][$k] != 0) {
|
||||
$s = 0.0;
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$s += $this->QR[$i][$k] * $Q[$i][$j];
|
||||
}
|
||||
$s = -$s/$this->QR[$k][$k];
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$Q[$i][$j] += $s * $this->QR[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
for($i = 0; $i < count($Q); ++$i) {
|
||||
for($j = 0; $j < count($Q); ++$j) {
|
||||
if(! isset($Q[$i][$j]) ) {
|
||||
$Q[$i][$j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
return new PHPExcel_Shared_JAMA_Matrix($Q);
|
||||
} // function getQ()
|
||||
|
||||
|
||||
/**
|
||||
* Least squares solution of A*X = B
|
||||
*
|
||||
* @param Matrix $B A Matrix with as many rows as A and any number of columns.
|
||||
* @return Matrix Matrix that minimizes the two norm of Q*R*X-B.
|
||||
*/
|
||||
public function solve($B) {
|
||||
if ($B->getRowDimension() == $this->m) {
|
||||
if ($this->isFullRank()) {
|
||||
// Copy right hand side
|
||||
$nx = $B->getColumnDimension();
|
||||
$X = $B->getArrayCopy();
|
||||
// Compute Y = transpose(Q)*B
|
||||
for ($k = 0; $k < $this->n; ++$k) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$s = 0.0;
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$s += $this->QR[$i][$k] * $X[$i][$j];
|
||||
}
|
||||
$s = -$s/$this->QR[$k][$k];
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$X[$i][$j] += $s * $this->QR[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Solve R*X = Y;
|
||||
for ($k = $this->n-1; $k >= 0; --$k) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$k][$j] /= $this->Rdiag[$k];
|
||||
}
|
||||
for ($i = 0; $i < $k; ++$i) {
|
||||
for ($j = 0; $j < $nx; ++$j) {
|
||||
$X[$i][$j] -= $X[$k][$j]* $this->QR[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
$X = new PHPExcel_Shared_JAMA_Matrix($X);
|
||||
return ($X->getMatrix(0, $this->n-1, 0, $nx));
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(self::MatrixRankException);
|
||||
}
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException);
|
||||
}
|
||||
} // function solve()
|
||||
|
||||
} // PHPExcel_Shared_JAMA_class QRDecomposition
|
526
extend/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php
Executable file
526
extend/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php
Executable file
@ -0,0 +1,526 @@
|
||||
<?php
|
||||
/**
|
||||
* @package JAMA
|
||||
*
|
||||
* For an m-by-n matrix A with m >= n, the singular value decomposition is
|
||||
* an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
|
||||
* an n-by-n orthogonal matrix V so that A = U*S*V'.
|
||||
*
|
||||
* The singular values, sigma[$k] = S[$k][$k], are ordered so that
|
||||
* sigma[0] >= sigma[1] >= ... >= sigma[n-1].
|
||||
*
|
||||
* The singular value decompostion always exists, so the constructor will
|
||||
* never fail. The matrix condition number and the effective numerical
|
||||
* rank can be computed from this decomposition.
|
||||
*
|
||||
* @author Paul Meagher
|
||||
* @license PHP v3.0
|
||||
* @version 1.1
|
||||
*/
|
||||
class SingularValueDecomposition {
|
||||
|
||||
/**
|
||||
* Internal storage of U.
|
||||
* @var array
|
||||
*/
|
||||
private $U = array();
|
||||
|
||||
/**
|
||||
* Internal storage of V.
|
||||
* @var array
|
||||
*/
|
||||
private $V = array();
|
||||
|
||||
/**
|
||||
* Internal storage of singular values.
|
||||
* @var array
|
||||
*/
|
||||
private $s = array();
|
||||
|
||||
/**
|
||||
* Row dimension.
|
||||
* @var int
|
||||
*/
|
||||
private $m;
|
||||
|
||||
/**
|
||||
* Column dimension.
|
||||
* @var int
|
||||
*/
|
||||
private $n;
|
||||
|
||||
|
||||
/**
|
||||
* Construct the singular value decomposition
|
||||
*
|
||||
* Derived from LINPACK code.
|
||||
*
|
||||
* @param $A Rectangular matrix
|
||||
* @return Structure to access U, S and V.
|
||||
*/
|
||||
public function __construct($Arg) {
|
||||
|
||||
// Initialize.
|
||||
$A = $Arg->getArrayCopy();
|
||||
$this->m = $Arg->getRowDimension();
|
||||
$this->n = $Arg->getColumnDimension();
|
||||
$nu = min($this->m, $this->n);
|
||||
$e = array();
|
||||
$work = array();
|
||||
$wantu = true;
|
||||
$wantv = true;
|
||||
$nct = min($this->m - 1, $this->n);
|
||||
$nrt = max(0, min($this->n - 2, $this->m));
|
||||
|
||||
// Reduce A to bidiagonal form, storing the diagonal elements
|
||||
// in s and the super-diagonal elements in e.
|
||||
for ($k = 0; $k < max($nct,$nrt); ++$k) {
|
||||
|
||||
if ($k < $nct) {
|
||||
// Compute the transformation for the k-th column and
|
||||
// place the k-th diagonal in s[$k].
|
||||
// Compute 2-norm of k-th column without under/overflow.
|
||||
$this->s[$k] = 0;
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$this->s[$k] = hypo($this->s[$k], $A[$i][$k]);
|
||||
}
|
||||
if ($this->s[$k] != 0.0) {
|
||||
if ($A[$k][$k] < 0.0) {
|
||||
$this->s[$k] = -$this->s[$k];
|
||||
}
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$A[$i][$k] /= $this->s[$k];
|
||||
}
|
||||
$A[$k][$k] += 1.0;
|
||||
}
|
||||
$this->s[$k] = -$this->s[$k];
|
||||
}
|
||||
|
||||
for ($j = $k + 1; $j < $this->n; ++$j) {
|
||||
if (($k < $nct) & ($this->s[$k] != 0.0)) {
|
||||
// Apply the transformation.
|
||||
$t = 0;
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$t += $A[$i][$k] * $A[$i][$j];
|
||||
}
|
||||
$t = -$t / $A[$k][$k];
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$A[$i][$j] += $t * $A[$i][$k];
|
||||
}
|
||||
// Place the k-th row of A into e for the
|
||||
// subsequent calculation of the row transformation.
|
||||
$e[$j] = $A[$k][$j];
|
||||
}
|
||||
}
|
||||
|
||||
if ($wantu AND ($k < $nct)) {
|
||||
// Place the transformation in U for subsequent back
|
||||
// multiplication.
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$this->U[$i][$k] = $A[$i][$k];
|
||||
}
|
||||
}
|
||||
|
||||
if ($k < $nrt) {
|
||||
// Compute the k-th row transformation and place the
|
||||
// k-th super-diagonal in e[$k].
|
||||
// Compute 2-norm without under/overflow.
|
||||
$e[$k] = 0;
|
||||
for ($i = $k + 1; $i < $this->n; ++$i) {
|
||||
$e[$k] = hypo($e[$k], $e[$i]);
|
||||
}
|
||||
if ($e[$k] != 0.0) {
|
||||
if ($e[$k+1] < 0.0) {
|
||||
$e[$k] = -$e[$k];
|
||||
}
|
||||
for ($i = $k + 1; $i < $this->n; ++$i) {
|
||||
$e[$i] /= $e[$k];
|
||||
}
|
||||
$e[$k+1] += 1.0;
|
||||
}
|
||||
$e[$k] = -$e[$k];
|
||||
if (($k+1 < $this->m) AND ($e[$k] != 0.0)) {
|
||||
// Apply the transformation.
|
||||
for ($i = $k+1; $i < $this->m; ++$i) {
|
||||
$work[$i] = 0.0;
|
||||
}
|
||||
for ($j = $k+1; $j < $this->n; ++$j) {
|
||||
for ($i = $k+1; $i < $this->m; ++$i) {
|
||||
$work[$i] += $e[$j] * $A[$i][$j];
|
||||
}
|
||||
}
|
||||
for ($j = $k + 1; $j < $this->n; ++$j) {
|
||||
$t = -$e[$j] / $e[$k+1];
|
||||
for ($i = $k + 1; $i < $this->m; ++$i) {
|
||||
$A[$i][$j] += $t * $work[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($wantv) {
|
||||
// Place the transformation in V for subsequent
|
||||
// back multiplication.
|
||||
for ($i = $k + 1; $i < $this->n; ++$i) {
|
||||
$this->V[$i][$k] = $e[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the final bidiagonal matrix or order p.
|
||||
$p = min($this->n, $this->m + 1);
|
||||
if ($nct < $this->n) {
|
||||
$this->s[$nct] = $A[$nct][$nct];
|
||||
}
|
||||
if ($this->m < $p) {
|
||||
$this->s[$p-1] = 0.0;
|
||||
}
|
||||
if ($nrt + 1 < $p) {
|
||||
$e[$nrt] = $A[$nrt][$p-1];
|
||||
}
|
||||
$e[$p-1] = 0.0;
|
||||
// If required, generate U.
|
||||
if ($wantu) {
|
||||
for ($j = $nct; $j < $nu; ++$j) {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$this->U[$i][$j] = 0.0;
|
||||
}
|
||||
$this->U[$j][$j] = 1.0;
|
||||
}
|
||||
for ($k = $nct - 1; $k >= 0; --$k) {
|
||||
if ($this->s[$k] != 0.0) {
|
||||
for ($j = $k + 1; $j < $nu; ++$j) {
|
||||
$t = 0;
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$t += $this->U[$i][$k] * $this->U[$i][$j];
|
||||
}
|
||||
$t = -$t / $this->U[$k][$k];
|
||||
for ($i = $k; $i < $this->m; ++$i) {
|
||||
$this->U[$i][$j] += $t * $this->U[$i][$k];
|
||||
}
|
||||
}
|
||||
for ($i = $k; $i < $this->m; ++$i ) {
|
||||
$this->U[$i][$k] = -$this->U[$i][$k];
|
||||
}
|
||||
$this->U[$k][$k] = 1.0 + $this->U[$k][$k];
|
||||
for ($i = 0; $i < $k - 1; ++$i) {
|
||||
$this->U[$i][$k] = 0.0;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$this->U[$i][$k] = 0.0;
|
||||
}
|
||||
$this->U[$k][$k] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If required, generate V.
|
||||
if ($wantv) {
|
||||
for ($k = $this->n - 1; $k >= 0; --$k) {
|
||||
if (($k < $nrt) AND ($e[$k] != 0.0)) {
|
||||
for ($j = $k + 1; $j < $nu; ++$j) {
|
||||
$t = 0;
|
||||
for ($i = $k + 1; $i < $this->n; ++$i) {
|
||||
$t += $this->V[$i][$k]* $this->V[$i][$j];
|
||||
}
|
||||
$t = -$t / $this->V[$k+1][$k];
|
||||
for ($i = $k + 1; $i < $this->n; ++$i) {
|
||||
$this->V[$i][$j] += $t * $this->V[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
$this->V[$i][$k] = 0.0;
|
||||
}
|
||||
$this->V[$k][$k] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Main iteration loop for the singular values.
|
||||
$pp = $p - 1;
|
||||
$iter = 0;
|
||||
$eps = pow(2.0, -52.0);
|
||||
|
||||
while ($p > 0) {
|
||||
// Here is where a test for too many iterations would go.
|
||||
// This section of the program inspects for negligible
|
||||
// elements in the s and e arrays. On completion the
|
||||
// variables kase and k are set as follows:
|
||||
// kase = 1 if s(p) and e[k-1] are negligible and k<p
|
||||
// kase = 2 if s(k) is negligible and k<p
|
||||
// kase = 3 if e[k-1] is negligible, k<p, and
|
||||
// s(k), ..., s(p) are not negligible (qr step).
|
||||
// kase = 4 if e(p-1) is negligible (convergence).
|
||||
for ($k = $p - 2; $k >= -1; --$k) {
|
||||
if ($k == -1) {
|
||||
break;
|
||||
}
|
||||
if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) {
|
||||
$e[$k] = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($k == $p - 2) {
|
||||
$kase = 4;
|
||||
} else {
|
||||
for ($ks = $p - 1; $ks >= $k; --$ks) {
|
||||
if ($ks == $k) {
|
||||
break;
|
||||
}
|
||||
$t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.);
|
||||
if (abs($this->s[$ks]) <= $eps * $t) {
|
||||
$this->s[$ks] = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($ks == $k) {
|
||||
$kase = 3;
|
||||
} else if ($ks == $p-1) {
|
||||
$kase = 1;
|
||||
} else {
|
||||
$kase = 2;
|
||||
$k = $ks;
|
||||
}
|
||||
}
|
||||
++$k;
|
||||
|
||||
// Perform the task indicated by kase.
|
||||
switch ($kase) {
|
||||
// Deflate negligible s(p).
|
||||
case 1:
|
||||
$f = $e[$p-2];
|
||||
$e[$p-2] = 0.0;
|
||||
for ($j = $p - 2; $j >= $k; --$j) {
|
||||
$t = hypo($this->s[$j],$f);
|
||||
$cs = $this->s[$j] / $t;
|
||||
$sn = $f / $t;
|
||||
$this->s[$j] = $t;
|
||||
if ($j != $k) {
|
||||
$f = -$sn * $e[$j-1];
|
||||
$e[$j-1] = $cs * $e[$j-1];
|
||||
}
|
||||
if ($wantv) {
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
$t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1];
|
||||
$this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1];
|
||||
$this->V[$i][$j] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Split at negligible s(k).
|
||||
case 2:
|
||||
$f = $e[$k-1];
|
||||
$e[$k-1] = 0.0;
|
||||
for ($j = $k; $j < $p; ++$j) {
|
||||
$t = hypo($this->s[$j], $f);
|
||||
$cs = $this->s[$j] / $t;
|
||||
$sn = $f / $t;
|
||||
$this->s[$j] = $t;
|
||||
$f = -$sn * $e[$j];
|
||||
$e[$j] = $cs * $e[$j];
|
||||
if ($wantu) {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1];
|
||||
$this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1];
|
||||
$this->U[$i][$j] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Perform one qr step.
|
||||
case 3:
|
||||
// Calculate the shift.
|
||||
$scale = max(max(max(max(
|
||||
abs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])),
|
||||
abs($this->s[$k])), abs($e[$k]));
|
||||
$sp = $this->s[$p-1] / $scale;
|
||||
$spm1 = $this->s[$p-2] / $scale;
|
||||
$epm1 = $e[$p-2] / $scale;
|
||||
$sk = $this->s[$k] / $scale;
|
||||
$ek = $e[$k] / $scale;
|
||||
$b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0;
|
||||
$c = ($sp * $epm1) * ($sp * $epm1);
|
||||
$shift = 0.0;
|
||||
if (($b != 0.0) || ($c != 0.0)) {
|
||||
$shift = sqrt($b * $b + $c);
|
||||
if ($b < 0.0) {
|
||||
$shift = -$shift;
|
||||
}
|
||||
$shift = $c / ($b + $shift);
|
||||
}
|
||||
$f = ($sk + $sp) * ($sk - $sp) + $shift;
|
||||
$g = $sk * $ek;
|
||||
// Chase zeros.
|
||||
for ($j = $k; $j < $p-1; ++$j) {
|
||||
$t = hypo($f,$g);
|
||||
$cs = $f/$t;
|
||||
$sn = $g/$t;
|
||||
if ($j != $k) {
|
||||
$e[$j-1] = $t;
|
||||
}
|
||||
$f = $cs * $this->s[$j] + $sn * $e[$j];
|
||||
$e[$j] = $cs * $e[$j] - $sn * $this->s[$j];
|
||||
$g = $sn * $this->s[$j+1];
|
||||
$this->s[$j+1] = $cs * $this->s[$j+1];
|
||||
if ($wantv) {
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
$t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1];
|
||||
$this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1];
|
||||
$this->V[$i][$j] = $t;
|
||||
}
|
||||
}
|
||||
$t = hypo($f,$g);
|
||||
$cs = $f/$t;
|
||||
$sn = $g/$t;
|
||||
$this->s[$j] = $t;
|
||||
$f = $cs * $e[$j] + $sn * $this->s[$j+1];
|
||||
$this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1];
|
||||
$g = $sn * $e[$j+1];
|
||||
$e[$j+1] = $cs * $e[$j+1];
|
||||
if ($wantu && ($j < $this->m - 1)) {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1];
|
||||
$this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1];
|
||||
$this->U[$i][$j] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
$e[$p-2] = $f;
|
||||
$iter = $iter + 1;
|
||||
break;
|
||||
// Convergence.
|
||||
case 4:
|
||||
// Make the singular values positive.
|
||||
if ($this->s[$k] <= 0.0) {
|
||||
$this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0);
|
||||
if ($wantv) {
|
||||
for ($i = 0; $i <= $pp; ++$i) {
|
||||
$this->V[$i][$k] = -$this->V[$i][$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Order the singular values.
|
||||
while ($k < $pp) {
|
||||
if ($this->s[$k] >= $this->s[$k+1]) {
|
||||
break;
|
||||
}
|
||||
$t = $this->s[$k];
|
||||
$this->s[$k] = $this->s[$k+1];
|
||||
$this->s[$k+1] = $t;
|
||||
if ($wantv AND ($k < $this->n - 1)) {
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
$t = $this->V[$i][$k+1];
|
||||
$this->V[$i][$k+1] = $this->V[$i][$k];
|
||||
$this->V[$i][$k] = $t;
|
||||
}
|
||||
}
|
||||
if ($wantu AND ($k < $this->m-1)) {
|
||||
for ($i = 0; $i < $this->m; ++$i) {
|
||||
$t = $this->U[$i][$k+1];
|
||||
$this->U[$i][$k+1] = $this->U[$i][$k];
|
||||
$this->U[$i][$k] = $t;
|
||||
}
|
||||
}
|
||||
++$k;
|
||||
}
|
||||
$iter = 0;
|
||||
--$p;
|
||||
break;
|
||||
} // end switch
|
||||
} // end while
|
||||
|
||||
} // end constructor
|
||||
|
||||
|
||||
/**
|
||||
* Return the left singular vectors
|
||||
*
|
||||
* @access public
|
||||
* @return U
|
||||
*/
|
||||
public function getU() {
|
||||
return new Matrix($this->U, $this->m, min($this->m + 1, $this->n));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the right singular vectors
|
||||
*
|
||||
* @access public
|
||||
* @return V
|
||||
*/
|
||||
public function getV() {
|
||||
return new Matrix($this->V);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the one-dimensional array of singular values
|
||||
*
|
||||
* @access public
|
||||
* @return diagonal of S.
|
||||
*/
|
||||
public function getSingularValues() {
|
||||
return $this->s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the diagonal matrix of singular values
|
||||
*
|
||||
* @access public
|
||||
* @return S
|
||||
*/
|
||||
public function getS() {
|
||||
for ($i = 0; $i < $this->n; ++$i) {
|
||||
for ($j = 0; $j < $this->n; ++$j) {
|
||||
$S[$i][$j] = 0.0;
|
||||
}
|
||||
$S[$i][$i] = $this->s[$i];
|
||||
}
|
||||
return new Matrix($S);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Two norm
|
||||
*
|
||||
* @access public
|
||||
* @return max(S)
|
||||
*/
|
||||
public function norm2() {
|
||||
return $this->s[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Two norm condition number
|
||||
*
|
||||
* @access public
|
||||
* @return max(S)/min(S)
|
||||
*/
|
||||
public function cond() {
|
||||
return $this->s[0] / $this->s[min($this->m, $this->n) - 1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Effective numerical matrix rank
|
||||
*
|
||||
* @access public
|
||||
* @return Number of nonnegligible singular values.
|
||||
*/
|
||||
public function rank() {
|
||||
$eps = pow(2.0, -52.0);
|
||||
$tol = max($this->m, $this->n) * $this->s[0] * $eps;
|
||||
$r = 0;
|
||||
for ($i = 0; $i < count($this->s); ++$i) {
|
||||
if ($this->s[$i] > $tol) {
|
||||
++$r;
|
||||
}
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
} // class SingularValueDecomposition
|
82
extend/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php
Executable file
82
extend/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php
Executable file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* @package JAMA
|
||||
*
|
||||
* Error handling
|
||||
* @author Michael Bommarito
|
||||
* @version 01292005
|
||||
*/
|
||||
|
||||
//Language constant
|
||||
define('JAMALANG', 'EN');
|
||||
|
||||
|
||||
//All errors may be defined by the following format:
|
||||
//define('ExceptionName', N);
|
||||
//$error['lang'][ExceptionName] = 'Error message';
|
||||
$error = array();
|
||||
|
||||
/*
|
||||
I've used Babelfish and a little poor knowledge of Romance/Germanic languages for the translations here.
|
||||
Feel free to correct anything that looks amiss to you.
|
||||
*/
|
||||
|
||||
define('PolymorphicArgumentException', -1);
|
||||
$error['EN'][PolymorphicArgumentException] = "Invalid argument pattern for polymorphic function.";
|
||||
$error['FR'][PolymorphicArgumentException] = "Modèle inadmissible d'argument pour la fonction polymorphe.".
|
||||
$error['DE'][PolymorphicArgumentException] = "Unzulässiges Argumentmuster für polymorphe Funktion.";
|
||||
|
||||
define('ArgumentTypeException', -2);
|
||||
$error['EN'][ArgumentTypeException] = "Invalid argument type.";
|
||||
$error['FR'][ArgumentTypeException] = "Type inadmissible d'argument.";
|
||||
$error['DE'][ArgumentTypeException] = "Unzulässige Argumentart.";
|
||||
|
||||
define('ArgumentBoundsException', -3);
|
||||
$error['EN'][ArgumentBoundsException] = "Invalid argument range.";
|
||||
$error['FR'][ArgumentBoundsException] = "Gamme inadmissible d'argument.";
|
||||
$error['DE'][ArgumentBoundsException] = "Unzulässige Argumentstrecke.";
|
||||
|
||||
define('MatrixDimensionException', -4);
|
||||
$error['EN'][MatrixDimensionException] = "Matrix dimensions are not equal.";
|
||||
$error['FR'][MatrixDimensionException] = "Les dimensions de Matrix ne sont pas égales.";
|
||||
$error['DE'][MatrixDimensionException] = "Matrixmaße sind nicht gleich.";
|
||||
|
||||
define('PrecisionLossException', -5);
|
||||
$error['EN'][PrecisionLossException] = "Significant precision loss detected.";
|
||||
$error['FR'][PrecisionLossException] = "Perte significative de précision détectée.";
|
||||
$error['DE'][PrecisionLossException] = "Bedeutender Präzision Verlust ermittelte.";
|
||||
|
||||
define('MatrixSPDException', -6);
|
||||
$error['EN'][MatrixSPDException] = "Can only perform operation on symmetric positive definite matrix.";
|
||||
$error['FR'][MatrixSPDException] = "Perte significative de précision détectée.";
|
||||
$error['DE'][MatrixSPDException] = "Bedeutender Präzision Verlust ermittelte.";
|
||||
|
||||
define('MatrixSingularException', -7);
|
||||
$error['EN'][MatrixSingularException] = "Can only perform operation on singular matrix.";
|
||||
|
||||
define('MatrixRankException', -8);
|
||||
$error['EN'][MatrixRankException] = "Can only perform operation on full-rank matrix.";
|
||||
|
||||
define('ArrayLengthException', -9);
|
||||
$error['EN'][ArrayLengthException] = "Array length must be a multiple of m.";
|
||||
|
||||
define('RowLengthException', -10);
|
||||
$error['EN'][RowLengthException] = "All rows must have the same length.";
|
||||
|
||||
/**
|
||||
* Custom error handler
|
||||
* @param int $num Error number
|
||||
*/
|
||||
function JAMAError($errorNumber = null) {
|
||||
global $error;
|
||||
|
||||
if (isset($errorNumber)) {
|
||||
if (isset($error[JAMALANG][$errorNumber])) {
|
||||
return $error[JAMALANG][$errorNumber];
|
||||
} else {
|
||||
return $error['EN'][$errorNumber];
|
||||
}
|
||||
} else {
|
||||
return ("Invalid argument to JAMAError()");
|
||||
}
|
||||
}
|
43
extend/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php
Executable file
43
extend/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php
Executable file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* @package JAMA
|
||||
*
|
||||
* Pythagorean Theorem:
|
||||
*
|
||||
* a = 3
|
||||
* b = 4
|
||||
* r = sqrt(square(a) + square(b))
|
||||
* r = 5
|
||||
*
|
||||
* r = sqrt(a^2 + b^2) without under/overflow.
|
||||
*/
|
||||
function hypo($a, $b) {
|
||||
if (abs($a) > abs($b)) {
|
||||
$r = $b / $a;
|
||||
$r = abs($a) * sqrt(1 + $r * $r);
|
||||
} elseif ($b != 0) {
|
||||
$r = $a / $b;
|
||||
$r = abs($b) * sqrt(1 + $r * $r);
|
||||
} else {
|
||||
$r = 0.0;
|
||||
}
|
||||
return $r;
|
||||
} // function hypo()
|
||||
|
||||
|
||||
/**
|
||||
* Mike Bommarito's version.
|
||||
* Compute n-dimensional hyotheneuse.
|
||||
*
|
||||
function hypot() {
|
||||
$s = 0;
|
||||
foreach (func_get_args() as $d) {
|
||||
if (is_numeric($d)) {
|
||||
$s += pow($d, 2);
|
||||
} else {
|
||||
throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException));
|
||||
}
|
||||
}
|
||||
return sqrt($s);
|
||||
}
|
||||
*/
|
531
extend/phpexcel/PHPExcel/Shared/OLE.php
Executable file
531
extend/phpexcel/PHPExcel/Shared/OLE.php
Executable file
@ -0,0 +1,531 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Xavier Noguer <xnoguer@php.net> |
|
||||
// | Based on OLE::Storage_Lite by Kawai, Takanori |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: OLE.php,v 1.13 2007/03/07 14:38:25 schmidt Exp $
|
||||
|
||||
|
||||
/**
|
||||
* Array for storing OLE instances that are accessed from
|
||||
* OLE_ChainedBlockStream::stream_open().
|
||||
* @var array
|
||||
*/
|
||||
$GLOBALS['_OLE_INSTANCES'] = array();
|
||||
|
||||
/**
|
||||
* OLE package base class.
|
||||
*
|
||||
* @author Xavier Noguer <xnoguer@php.net>
|
||||
* @author Christian Schmidt <schmidt@php.net>
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_OLE
|
||||
*/
|
||||
class PHPExcel_Shared_OLE
|
||||
{
|
||||
const OLE_PPS_TYPE_ROOT = 5;
|
||||
const OLE_PPS_TYPE_DIR = 1;
|
||||
const OLE_PPS_TYPE_FILE = 2;
|
||||
const OLE_DATA_SIZE_SMALL = 0x1000;
|
||||
const OLE_LONG_INT_SIZE = 4;
|
||||
const OLE_PPS_SIZE = 0x80;
|
||||
|
||||
/**
|
||||
* The file handle for reading an OLE container
|
||||
* @var resource
|
||||
*/
|
||||
public $_file_handle;
|
||||
|
||||
/**
|
||||
* Array of PPS's found on the OLE container
|
||||
* @var array
|
||||
*/
|
||||
public $_list = array();
|
||||
|
||||
/**
|
||||
* Root directory of OLE container
|
||||
* @var OLE_PPS_Root
|
||||
*/
|
||||
public $root;
|
||||
|
||||
/**
|
||||
* Big Block Allocation Table
|
||||
* @var array (blockId => nextBlockId)
|
||||
*/
|
||||
public $bbat;
|
||||
|
||||
/**
|
||||
* Short Block Allocation Table
|
||||
* @var array (blockId => nextBlockId)
|
||||
*/
|
||||
public $sbat;
|
||||
|
||||
/**
|
||||
* Size of big blocks. This is usually 512.
|
||||
* @var int number of octets per block.
|
||||
*/
|
||||
public $bigBlockSize;
|
||||
|
||||
/**
|
||||
* Size of small blocks. This is usually 64.
|
||||
* @var int number of octets per block
|
||||
*/
|
||||
public $smallBlockSize;
|
||||
|
||||
/**
|
||||
* Reads an OLE container from the contents of the file given.
|
||||
*
|
||||
* @acces public
|
||||
* @param string $file
|
||||
* @return mixed true on success, PEAR_Error on failure
|
||||
*/
|
||||
public function read($file)
|
||||
{
|
||||
$fh = fopen($file, "r");
|
||||
if (!$fh) {
|
||||
throw new PHPExcel_Reader_Exception("Can't open file $file");
|
||||
}
|
||||
$this->_file_handle = $fh;
|
||||
|
||||
$signature = fread($fh, 8);
|
||||
if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) {
|
||||
throw new PHPExcel_Reader_Exception("File doesn't seem to be an OLE container.");
|
||||
}
|
||||
fseek($fh, 28);
|
||||
if (fread($fh, 2) != "\xFE\xFF") {
|
||||
// This shouldn't be a problem in practice
|
||||
throw new PHPExcel_Reader_Exception("Only Little-Endian encoding is supported.");
|
||||
}
|
||||
// Size of blocks and short blocks in bytes
|
||||
$this->bigBlockSize = pow(2, self::_readInt2($fh));
|
||||
$this->smallBlockSize = pow(2, self::_readInt2($fh));
|
||||
|
||||
// Skip UID, revision number and version number
|
||||
fseek($fh, 44);
|
||||
// Number of blocks in Big Block Allocation Table
|
||||
$bbatBlockCount = self::_readInt4($fh);
|
||||
|
||||
// Root chain 1st block
|
||||
$directoryFirstBlockId = self::_readInt4($fh);
|
||||
|
||||
// Skip unused bytes
|
||||
fseek($fh, 56);
|
||||
// Streams shorter than this are stored using small blocks
|
||||
$this->bigBlockThreshold = self::_readInt4($fh);
|
||||
// Block id of first sector in Short Block Allocation Table
|
||||
$sbatFirstBlockId = self::_readInt4($fh);
|
||||
// Number of blocks in Short Block Allocation Table
|
||||
$sbbatBlockCount = self::_readInt4($fh);
|
||||
// Block id of first sector in Master Block Allocation Table
|
||||
$mbatFirstBlockId = self::_readInt4($fh);
|
||||
// Number of blocks in Master Block Allocation Table
|
||||
$mbbatBlockCount = self::_readInt4($fh);
|
||||
$this->bbat = array();
|
||||
|
||||
// Remaining 4 * 109 bytes of current block is beginning of Master
|
||||
// Block Allocation Table
|
||||
$mbatBlocks = array();
|
||||
for ($i = 0; $i < 109; ++$i) {
|
||||
$mbatBlocks[] = self::_readInt4($fh);
|
||||
}
|
||||
|
||||
// Read rest of Master Block Allocation Table (if any is left)
|
||||
$pos = $this->_getBlockOffset($mbatFirstBlockId);
|
||||
for ($i = 0; $i < $mbbatBlockCount; ++$i) {
|
||||
fseek($fh, $pos);
|
||||
for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) {
|
||||
$mbatBlocks[] = self::_readInt4($fh);
|
||||
}
|
||||
// Last block id in each block points to next block
|
||||
$pos = $this->_getBlockOffset(self::_readInt4($fh));
|
||||
}
|
||||
|
||||
// Read Big Block Allocation Table according to chain specified by
|
||||
// $mbatBlocks
|
||||
for ($i = 0; $i < $bbatBlockCount; ++$i) {
|
||||
$pos = $this->_getBlockOffset($mbatBlocks[$i]);
|
||||
fseek($fh, $pos);
|
||||
for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) {
|
||||
$this->bbat[] = self::_readInt4($fh);
|
||||
}
|
||||
}
|
||||
|
||||
// Read short block allocation table (SBAT)
|
||||
$this->sbat = array();
|
||||
$shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4;
|
||||
$sbatFh = $this->getStream($sbatFirstBlockId);
|
||||
for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) {
|
||||
$this->sbat[$blockId] = self::_readInt4($sbatFh);
|
||||
}
|
||||
fclose($sbatFh);
|
||||
|
||||
$this->_readPpsWks($directoryFirstBlockId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int block id
|
||||
* @param int byte offset from beginning of file
|
||||
* @access public
|
||||
*/
|
||||
public function _getBlockOffset($blockId)
|
||||
{
|
||||
return 512 + $blockId * $this->bigBlockSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream for use with fread() etc. External callers should
|
||||
* use PHPExcel_Shared_OLE_PPS_File::getStream().
|
||||
* @param int|PPS block id or PPS
|
||||
* @return resource read-only stream
|
||||
*/
|
||||
public function getStream($blockIdOrPps)
|
||||
{
|
||||
static $isRegistered = false;
|
||||
if (!$isRegistered) {
|
||||
stream_wrapper_register('ole-chainedblockstream',
|
||||
'PHPExcel_Shared_OLE_ChainedBlockStream');
|
||||
$isRegistered = true;
|
||||
}
|
||||
|
||||
// Store current instance in global array, so that it can be accessed
|
||||
// in OLE_ChainedBlockStream::stream_open().
|
||||
// Object is removed from self::$instances in OLE_Stream::close().
|
||||
$GLOBALS['_OLE_INSTANCES'][] = $this;
|
||||
$instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES']));
|
||||
|
||||
$path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId;
|
||||
if ($blockIdOrPps instanceof PHPExcel_Shared_OLE_PPS) {
|
||||
$path .= '&blockId=' . $blockIdOrPps->_StartBlock;
|
||||
$path .= '&size=' . $blockIdOrPps->Size;
|
||||
} else {
|
||||
$path .= '&blockId=' . $blockIdOrPps;
|
||||
}
|
||||
return fopen($path, 'r');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a signed char.
|
||||
* @param resource file handle
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
private static function _readInt1($fh)
|
||||
{
|
||||
list(, $tmp) = unpack("c", fread($fh, 1));
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned short (2 octets).
|
||||
* @param resource file handle
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
private static function _readInt2($fh)
|
||||
{
|
||||
list(, $tmp) = unpack("v", fread($fh, 2));
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned long (4 octets).
|
||||
* @param resource file handle
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
private static function _readInt4($fh)
|
||||
{
|
||||
list(, $tmp) = unpack("V", fread($fh, 4));
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about all PPS's on the OLE container from the PPS WK's
|
||||
* creates an OLE_PPS object for each one.
|
||||
*
|
||||
* @access public
|
||||
* @param integer the block id of the first block
|
||||
* @return mixed true on success, PEAR_Error on failure
|
||||
*/
|
||||
public function _readPpsWks($blockId)
|
||||
{
|
||||
$fh = $this->getStream($blockId);
|
||||
for ($pos = 0; ; $pos += 128) {
|
||||
fseek($fh, $pos, SEEK_SET);
|
||||
$nameUtf16 = fread($fh, 64);
|
||||
$nameLength = self::_readInt2($fh);
|
||||
$nameUtf16 = substr($nameUtf16, 0, $nameLength - 2);
|
||||
// Simple conversion from UTF-16LE to ISO-8859-1
|
||||
$name = str_replace("\x00", "", $nameUtf16);
|
||||
$type = self::_readInt1($fh);
|
||||
switch ($type) {
|
||||
case self::OLE_PPS_TYPE_ROOT:
|
||||
$pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array());
|
||||
$this->root = $pps;
|
||||
break;
|
||||
case self::OLE_PPS_TYPE_DIR:
|
||||
$pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null,
|
||||
null, null, null, null, array());
|
||||
break;
|
||||
case self::OLE_PPS_TYPE_FILE:
|
||||
$pps = new PHPExcel_Shared_OLE_PPS_File($name);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
fseek($fh, 1, SEEK_CUR);
|
||||
$pps->Type = $type;
|
||||
$pps->Name = $name;
|
||||
$pps->PrevPps = self::_readInt4($fh);
|
||||
$pps->NextPps = self::_readInt4($fh);
|
||||
$pps->DirPps = self::_readInt4($fh);
|
||||
fseek($fh, 20, SEEK_CUR);
|
||||
$pps->Time1st = self::OLE2LocalDate(fread($fh, 8));
|
||||
$pps->Time2nd = self::OLE2LocalDate(fread($fh, 8));
|
||||
$pps->_StartBlock = self::_readInt4($fh);
|
||||
$pps->Size = self::_readInt4($fh);
|
||||
$pps->No = count($this->_list);
|
||||
$this->_list[] = $pps;
|
||||
|
||||
// check if the PPS tree (starting from root) is complete
|
||||
if (isset($this->root) &&
|
||||
$this->_ppsTreeComplete($this->root->No)) {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose($fh);
|
||||
|
||||
// Initialize $pps->children on directories
|
||||
foreach ($this->_list as $pps) {
|
||||
if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) {
|
||||
$nos = array($pps->DirPps);
|
||||
$pps->children = array();
|
||||
while ($nos) {
|
||||
$no = array_pop($nos);
|
||||
if ($no != -1) {
|
||||
$childPps = $this->_list[$no];
|
||||
$nos[] = $childPps->PrevPps;
|
||||
$nos[] = $childPps->NextPps;
|
||||
$pps->children[] = $childPps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* It checks whether the PPS tree is complete (all PPS's read)
|
||||
* starting with the given PPS (not necessarily root)
|
||||
*
|
||||
* @access public
|
||||
* @param integer $index The index of the PPS from which we are checking
|
||||
* @return boolean Whether the PPS tree for the given PPS is complete
|
||||
*/
|
||||
public function _ppsTreeComplete($index)
|
||||
{
|
||||
return isset($this->_list[$index]) &&
|
||||
($pps = $this->_list[$index]) &&
|
||||
($pps->PrevPps == -1 ||
|
||||
$this->_ppsTreeComplete($pps->PrevPps)) &&
|
||||
($pps->NextPps == -1 ||
|
||||
$this->_ppsTreeComplete($pps->NextPps)) &&
|
||||
($pps->DirPps == -1 ||
|
||||
$this->_ppsTreeComplete($pps->DirPps));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a PPS is a File PPS or not.
|
||||
* If there is no PPS for the index given, it will return false.
|
||||
*
|
||||
* @access public
|
||||
* @param integer $index The index for the PPS
|
||||
* @return bool true if it's a File PPS, false otherwise
|
||||
*/
|
||||
public function isFile($index)
|
||||
{
|
||||
if (isset($this->_list[$index])) {
|
||||
return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a PPS is a Root PPS or not.
|
||||
* If there is no PPS for the index given, it will return false.
|
||||
*
|
||||
* @access public
|
||||
* @param integer $index The index for the PPS.
|
||||
* @return bool true if it's a Root PPS, false otherwise
|
||||
*/
|
||||
public function isRoot($index)
|
||||
{
|
||||
if (isset($this->_list[$index])) {
|
||||
return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the total number of PPS's found in the OLE container.
|
||||
*
|
||||
* @access public
|
||||
* @return integer The total number of PPS's found in the OLE container
|
||||
*/
|
||||
public function ppsTotal()
|
||||
{
|
||||
return count($this->_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data from a PPS
|
||||
* If there is no PPS for the index given, it will return an empty string.
|
||||
*
|
||||
* @access public
|
||||
* @param integer $index The index for the PPS
|
||||
* @param integer $position The position from which to start reading
|
||||
* (relative to the PPS)
|
||||
* @param integer $length The amount of bytes to read (at most)
|
||||
* @return string The binary string containing the data requested
|
||||
* @see OLE_PPS_File::getStream()
|
||||
*/
|
||||
public function getData($index, $position, $length)
|
||||
{
|
||||
// if position is not valid return empty string
|
||||
if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) {
|
||||
return '';
|
||||
}
|
||||
$fh = $this->getStream($this->_list[$index]);
|
||||
$data = stream_get_contents($fh, $length, $position);
|
||||
fclose($fh);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data length from a PPS
|
||||
* If there is no PPS for the index given, it will return 0.
|
||||
*
|
||||
* @access public
|
||||
* @param integer $index The index for the PPS
|
||||
* @return integer The amount of bytes in data the PPS has
|
||||
*/
|
||||
public function getDataLength($index)
|
||||
{
|
||||
if (isset($this->_list[$index])) {
|
||||
return $this->_list[$index]->Size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to transform ASCII text to Unicode
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param string $ascii The ASCII string to transform
|
||||
* @return string The string in Unicode
|
||||
*/
|
||||
public static function Asc2Ucs($ascii)
|
||||
{
|
||||
$rawname = '';
|
||||
for ($i = 0; $i < strlen($ascii); ++$i) {
|
||||
$rawname .= $ascii{$i} . "\x00";
|
||||
}
|
||||
return $rawname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function
|
||||
* Returns a string for the OLE container with the date given
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param integer $date A timestamp
|
||||
* @return string The string for the OLE container
|
||||
*/
|
||||
public static function LocalDate2OLE($date = null)
|
||||
{
|
||||
if (!isset($date)) {
|
||||
return "\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||
}
|
||||
|
||||
// factor used for separating numbers into 4 bytes parts
|
||||
$factor = pow(2, 32);
|
||||
|
||||
// days from 1-1-1601 until the beggining of UNIX era
|
||||
$days = 134774;
|
||||
// calculate seconds
|
||||
$big_date = $days*24*3600 + gmmktime(date("H",$date),date("i",$date),date("s",$date),
|
||||
date("m",$date),date("d",$date),date("Y",$date));
|
||||
// multiply just to make MS happy
|
||||
$big_date *= 10000000;
|
||||
|
||||
$high_part = floor($big_date / $factor);
|
||||
// lower 4 bytes
|
||||
$low_part = floor((($big_date / $factor) - $high_part) * $factor);
|
||||
|
||||
// Make HEX string
|
||||
$res = '';
|
||||
|
||||
for ($i = 0; $i < 4; ++$i) {
|
||||
$hex = $low_part % 0x100;
|
||||
$res .= pack('c', $hex);
|
||||
$low_part /= 0x100;
|
||||
}
|
||||
for ($i = 0; $i < 4; ++$i) {
|
||||
$hex = $high_part % 0x100;
|
||||
$res .= pack('c', $hex);
|
||||
$high_part /= 0x100;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp from an OLE container's date
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param integer $string A binary string with the encoded date
|
||||
* @return string The timestamp corresponding to the string
|
||||
*/
|
||||
public static function OLE2LocalDate($string)
|
||||
{
|
||||
if (strlen($string) != 8) {
|
||||
return new PEAR_Error("Expecting 8 byte string");
|
||||
}
|
||||
|
||||
// factor used for separating numbers into 4 bytes parts
|
||||
$factor = pow(2,32);
|
||||
list(, $high_part) = unpack('V', substr($string, 4, 4));
|
||||
list(, $low_part) = unpack('V', substr($string, 0, 4));
|
||||
|
||||
$big_date = ($high_part * $factor) + $low_part;
|
||||
// translate to seconds
|
||||
$big_date /= 10000000;
|
||||
|
||||
// days from 1-1-1601 until the beggining of UNIX era
|
||||
$days = 134774;
|
||||
|
||||
// translate to seconds from beggining of UNIX era
|
||||
$big_date -= $days * 24 * 3600;
|
||||
return floor($big_date);
|
||||
}
|
||||
}
|
230
extend/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php
Executable file
230
extend/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php
Executable file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (C) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_OLE
|
||||
* @copyright Copyright (c) 2006 - 2007 Christian Schmidt
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_OLE_ChainedBlockStream
|
||||
*
|
||||
* Stream wrapper for reading data stored in an OLE file. Implements methods
|
||||
* for PHP's stream_wrapper_register(). For creating streams using this
|
||||
* wrapper, use PHPExcel_Shared_OLE_PPS_File::getStream().
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_OLE
|
||||
*/
|
||||
class PHPExcel_Shared_OLE_ChainedBlockStream
|
||||
{
|
||||
/**
|
||||
* The OLE container of the file that is being read.
|
||||
* @var OLE
|
||||
*/
|
||||
public $ole;
|
||||
|
||||
/**
|
||||
* Parameters specified by fopen().
|
||||
* @var array
|
||||
*/
|
||||
public $params;
|
||||
|
||||
/**
|
||||
* The binary data of the file.
|
||||
* @var string
|
||||
*/
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* The file pointer.
|
||||
* @var int byte offset
|
||||
*/
|
||||
public $pos;
|
||||
|
||||
/**
|
||||
* Implements support for fopen().
|
||||
* For creating streams using this wrapper, use OLE_PPS_File::getStream().
|
||||
*
|
||||
* @param string $path resource name including scheme, e.g.
|
||||
* ole-chainedblockstream://oleInstanceId=1
|
||||
* @param string $mode only "r" is supported
|
||||
* @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH
|
||||
* @param string &$openedPath absolute path of the opened stream (out parameter)
|
||||
* @return bool true on success
|
||||
*/
|
||||
public function stream_open($path, $mode, $options, &$openedPath)
|
||||
{
|
||||
if ($mode != 'r') {
|
||||
if ($options & STREAM_REPORT_ERRORS) {
|
||||
trigger_error('Only reading is supported', E_USER_WARNING);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 25 is length of "ole-chainedblockstream://"
|
||||
parse_str(substr($path, 25), $this->params);
|
||||
if (!isset($this->params['oleInstanceId'],
|
||||
$this->params['blockId'],
|
||||
$GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) {
|
||||
|
||||
if ($options & STREAM_REPORT_ERRORS) {
|
||||
trigger_error('OLE stream not found', E_USER_WARNING);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']];
|
||||
|
||||
$blockId = $this->params['blockId'];
|
||||
$this->data = '';
|
||||
if (isset($this->params['size']) &&
|
||||
$this->params['size'] < $this->ole->bigBlockThreshold &&
|
||||
$blockId != $this->ole->root->_StartBlock) {
|
||||
|
||||
// Block id refers to small blocks
|
||||
$rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock);
|
||||
while ($blockId != -2) {
|
||||
$pos = $rootPos + $blockId * $this->ole->bigBlockSize;
|
||||
$blockId = $this->ole->sbat[$blockId];
|
||||
fseek($this->ole->_file_handle, $pos);
|
||||
$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
|
||||
}
|
||||
} else {
|
||||
// Block id refers to big blocks
|
||||
while ($blockId != -2) {
|
||||
$pos = $this->ole->_getBlockOffset($blockId);
|
||||
fseek($this->ole->_file_handle, $pos);
|
||||
$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
|
||||
$blockId = $this->ole->bbat[$blockId];
|
||||
}
|
||||
}
|
||||
if (isset($this->params['size'])) {
|
||||
$this->data = substr($this->data, 0, $this->params['size']);
|
||||
}
|
||||
|
||||
if ($options & STREAM_USE_PATH) {
|
||||
$openedPath = $path;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fclose().
|
||||
*
|
||||
*/
|
||||
public function stream_close()
|
||||
{
|
||||
$this->ole = null;
|
||||
unset($GLOBALS['_OLE_INSTANCES']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fread(), fgets() etc.
|
||||
*
|
||||
* @param int $count maximum number of bytes to read
|
||||
* @return string
|
||||
*/
|
||||
public function stream_read($count)
|
||||
{
|
||||
if ($this->stream_eof()) {
|
||||
return false;
|
||||
}
|
||||
$s = substr($this->data, $this->pos, $count);
|
||||
$this->pos += $count;
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for feof().
|
||||
*
|
||||
* @return bool TRUE if the file pointer is at EOF; otherwise FALSE
|
||||
*/
|
||||
public function stream_eof()
|
||||
{
|
||||
// As we don't support below 5.2 anymore, this is simply redundancy and overhead
|
||||
// $eof = $this->pos >= strlen($this->data);
|
||||
// // Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508
|
||||
// if (version_compare(PHP_VERSION, '5.0', '>=') &&
|
||||
// version_compare(PHP_VERSION, '5.1', '<')) {
|
||||
// $eof = !$eof;
|
||||
// }
|
||||
// return $eof;
|
||||
return $this->pos >= strlen($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the file pointer, i.e. its offset into the file
|
||||
* stream. Implements support for ftell().
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fseek().
|
||||
*
|
||||
* @param int $offset byte offset
|
||||
* @param int $whence SEEK_SET, SEEK_CUR or SEEK_END
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if ($whence == SEEK_SET && $offset >= 0) {
|
||||
$this->pos = $offset;
|
||||
} elseif ($whence == SEEK_CUR && -$offset <= $this->pos) {
|
||||
$this->pos += $offset;
|
||||
} elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) {
|
||||
$this->pos = strlen($this->data) + $offset;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fstat(). Currently the only supported field is
|
||||
* "size".
|
||||
* @return array
|
||||
*/
|
||||
public function stream_stat()
|
||||
{
|
||||
return array(
|
||||
'size' => strlen($this->data),
|
||||
);
|
||||
}
|
||||
|
||||
// Methods used by stream_wrapper_register() that are not implemented:
|
||||
// bool stream_flush ( void )
|
||||
// int stream_write ( string data )
|
||||
// bool rename ( string path_from, string path_to )
|
||||
// bool mkdir ( string path, int mode, int options )
|
||||
// bool rmdir ( string path, int options )
|
||||
// bool dir_opendir ( string path, int options )
|
||||
// array url_stat ( string path, int flags )
|
||||
// string dir_readdir ( void )
|
||||
// bool dir_rewinddir ( void )
|
||||
// bool dir_closedir ( void )
|
||||
}
|
230
extend/phpexcel/PHPExcel/Shared/OLE/PPS.php
Executable file
230
extend/phpexcel/PHPExcel/Shared/OLE/PPS.php
Executable file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Xavier Noguer <xnoguer@php.net> |
|
||||
// | Based on OLE::Storage_Lite by Kawai, Takanori |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: PPS.php,v 1.7 2007/02/13 21:00:42 schmidt Exp $
|
||||
|
||||
|
||||
/**
|
||||
* Class for creating PPS's for OLE containers
|
||||
*
|
||||
* @author Xavier Noguer <xnoguer@php.net>
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_OLE
|
||||
*/
|
||||
class PHPExcel_Shared_OLE_PPS
|
||||
{
|
||||
/**
|
||||
* The PPS index
|
||||
* @var integer
|
||||
*/
|
||||
public $No;
|
||||
|
||||
/**
|
||||
* The PPS name (in Unicode)
|
||||
* @var string
|
||||
*/
|
||||
public $Name;
|
||||
|
||||
/**
|
||||
* The PPS type. Dir, Root or File
|
||||
* @var integer
|
||||
*/
|
||||
public $Type;
|
||||
|
||||
/**
|
||||
* The index of the previous PPS
|
||||
* @var integer
|
||||
*/
|
||||
public $PrevPps;
|
||||
|
||||
/**
|
||||
* The index of the next PPS
|
||||
* @var integer
|
||||
*/
|
||||
public $NextPps;
|
||||
|
||||
/**
|
||||
* The index of it's first child if this is a Dir or Root PPS
|
||||
* @var integer
|
||||
*/
|
||||
public $DirPps;
|
||||
|
||||
/**
|
||||
* A timestamp
|
||||
* @var integer
|
||||
*/
|
||||
public $Time1st;
|
||||
|
||||
/**
|
||||
* A timestamp
|
||||
* @var integer
|
||||
*/
|
||||
public $Time2nd;
|
||||
|
||||
/**
|
||||
* Starting block (small or big) for this PPS's data inside the container
|
||||
* @var integer
|
||||
*/
|
||||
public $_StartBlock;
|
||||
|
||||
/**
|
||||
* The size of the PPS's data (in bytes)
|
||||
* @var integer
|
||||
*/
|
||||
public $Size;
|
||||
|
||||
/**
|
||||
* The PPS's data (only used if it's not using a temporary file)
|
||||
* @var string
|
||||
*/
|
||||
public $_data;
|
||||
|
||||
/**
|
||||
* Array of child PPS's (only used by Root and Dir PPS's)
|
||||
* @var array
|
||||
*/
|
||||
public $children = array();
|
||||
|
||||
/**
|
||||
* Pointer to OLE container
|
||||
* @var OLE
|
||||
*/
|
||||
public $ole;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @access public
|
||||
* @param integer $No The PPS index
|
||||
* @param string $name The PPS name
|
||||
* @param integer $type The PPS type. Dir, Root or File
|
||||
* @param integer $prev The index of the previous PPS
|
||||
* @param integer $next The index of the next PPS
|
||||
* @param integer $dir The index of it's first child if this is a Dir or Root PPS
|
||||
* @param integer $time_1st A timestamp
|
||||
* @param integer $time_2nd A timestamp
|
||||
* @param string $data The (usually binary) source data of the PPS
|
||||
* @param array $children Array containing children PPS for this PPS
|
||||
*/
|
||||
public function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children)
|
||||
{
|
||||
$this->No = $No;
|
||||
$this->Name = $name;
|
||||
$this->Type = $type;
|
||||
$this->PrevPps = $prev;
|
||||
$this->NextPps = $next;
|
||||
$this->DirPps = $dir;
|
||||
$this->Time1st = $time_1st;
|
||||
$this->Time2nd = $time_2nd;
|
||||
$this->_data = $data;
|
||||
$this->children = $children;
|
||||
if ($data != '') {
|
||||
$this->Size = strlen($data);
|
||||
} else {
|
||||
$this->Size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of data saved for this PPS
|
||||
*
|
||||
* @access public
|
||||
* @return integer The amount of data (in bytes)
|
||||
*/
|
||||
public function _DataLen()
|
||||
{
|
||||
if (!isset($this->_data)) {
|
||||
return 0;
|
||||
}
|
||||
//if (isset($this->_PPS_FILE)) {
|
||||
// fseek($this->_PPS_FILE, 0);
|
||||
// $stats = fstat($this->_PPS_FILE);
|
||||
// return $stats[7];
|
||||
//} else {
|
||||
return strlen($this->_data);
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with the PPS's WK (What is a WK?)
|
||||
*
|
||||
* @access public
|
||||
* @return string The binary string
|
||||
*/
|
||||
public function _getPpsWk()
|
||||
{
|
||||
$ret = str_pad($this->Name,64,"\x00");
|
||||
|
||||
$ret .= pack("v", strlen($this->Name) + 2) // 66
|
||||
. pack("c", $this->Type) // 67
|
||||
. pack("c", 0x00) //UK // 68
|
||||
. pack("V", $this->PrevPps) //Prev // 72
|
||||
. pack("V", $this->NextPps) //Next // 76
|
||||
. pack("V", $this->DirPps) //Dir // 80
|
||||
. "\x00\x09\x02\x00" // 84
|
||||
. "\x00\x00\x00\x00" // 88
|
||||
. "\xc0\x00\x00\x00" // 92
|
||||
. "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root
|
||||
. "\x00\x00\x00\x00" // 100
|
||||
. PHPExcel_Shared_OLE::LocalDate2OLE($this->Time1st) // 108
|
||||
. PHPExcel_Shared_OLE::LocalDate2OLE($this->Time2nd) // 116
|
||||
. pack("V", isset($this->_StartBlock)?
|
||||
$this->_StartBlock:0) // 120
|
||||
. pack("V", $this->Size) // 124
|
||||
. pack("V", 0); // 128
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates index and pointers to previous, next and children PPS's for this
|
||||
* PPS. I don't think it'll work with Dir PPS's.
|
||||
*
|
||||
* @access public
|
||||
* @param array &$raList Reference to the array of PPS's for the whole OLE
|
||||
* container
|
||||
* @return integer The index for this PPS
|
||||
*/
|
||||
public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0)
|
||||
{
|
||||
if ( !is_array($to_save) || (empty($to_save)) ) {
|
||||
return 0xFFFFFFFF;
|
||||
} elseif( count($to_save) == 1 ) {
|
||||
$cnt = count($raList);
|
||||
// If the first entry, it's the root... Don't clone it!
|
||||
$raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0];
|
||||
$raList[$cnt]->No = $cnt;
|
||||
$raList[$cnt]->PrevPps = 0xFFFFFFFF;
|
||||
$raList[$cnt]->NextPps = 0xFFFFFFFF;
|
||||
$raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);
|
||||
} else {
|
||||
$iPos = floor(count($to_save) / 2);
|
||||
$aPrev = array_slice($to_save, 0, $iPos);
|
||||
$aNext = array_slice($to_save, $iPos + 1);
|
||||
$cnt = count($raList);
|
||||
// If the first entry, it's the root... Don't clone it!
|
||||
$raList[$cnt] = ( $depth == 0 ) ? $to_save[$iPos] : clone $to_save[$iPos];
|
||||
$raList[$cnt]->No = $cnt;
|
||||
$raList[$cnt]->PrevPps = self::_savePpsSetPnt($raList, $aPrev, $depth++);
|
||||
$raList[$cnt]->NextPps = self::_savePpsSetPnt($raList, $aNext, $depth++);
|
||||
$raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);
|
||||
|
||||
}
|
||||
return $cnt;
|
||||
}
|
||||
}
|
84
extend/phpexcel/PHPExcel/Shared/OLE/PPS/File.php
Executable file
84
extend/phpexcel/PHPExcel/Shared/OLE/PPS/File.php
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Xavier Noguer <xnoguer@php.net> |
|
||||
// | Based on OLE::Storage_Lite by Kawai, Takanori |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: File.php,v 1.11 2007/02/13 21:00:42 schmidt Exp $
|
||||
|
||||
|
||||
/**
|
||||
* Class for creating File PPS's for OLE containers
|
||||
*
|
||||
* @author Xavier Noguer <xnoguer@php.net>
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_OLE
|
||||
*/
|
||||
class PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS
|
||||
{
|
||||
/**
|
||||
* The constructor
|
||||
*
|
||||
* @access public
|
||||
* @param string $name The name of the file (in Unicode)
|
||||
* @see OLE::Asc2Ucs()
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
parent::__construct(
|
||||
null,
|
||||
$name,
|
||||
PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
'',
|
||||
array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization method. Has to be called right after OLE_PPS_File().
|
||||
*
|
||||
* @access public
|
||||
* @return mixed true on success
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data to PPS
|
||||
*
|
||||
* @access public
|
||||
* @param string $data The data to append
|
||||
*/
|
||||
public function append($data)
|
||||
{
|
||||
$this->_data .= $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream for reading this file using fread() etc.
|
||||
* @return resource a read-only stream
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
$this->ole->getStream($this);
|
||||
}
|
||||
}
|
467
extend/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php
Executable file
467
extend/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php
Executable file
@ -0,0 +1,467 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Xavier Noguer <xnoguer@php.net> |
|
||||
// | Based on OLE::Storage_Lite by Kawai, Takanori |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Root.php,v 1.9 2005/04/23 21:53:49 dufuz Exp $
|
||||
|
||||
|
||||
/**
|
||||
* Class for creating Root PPS's for OLE containers
|
||||
*
|
||||
* @author Xavier Noguer <xnoguer@php.net>
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_OLE
|
||||
*/
|
||||
class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS
|
||||
{
|
||||
|
||||
/**
|
||||
* Directory for temporary files
|
||||
* @var string
|
||||
*/
|
||||
protected $_tmp_dir = NULL;
|
||||
|
||||
/**
|
||||
* @param integer $time_1st A timestamp
|
||||
* @param integer $time_2nd A timestamp
|
||||
*/
|
||||
public function __construct($time_1st, $time_2nd, $raChild)
|
||||
{
|
||||
$this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir();
|
||||
|
||||
parent::__construct(
|
||||
null,
|
||||
PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'),
|
||||
PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
$time_1st,
|
||||
$time_2nd,
|
||||
null,
|
||||
$raChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for saving the whole OLE container (including files).
|
||||
* In fact, if called with an empty argument (or '-'), it saves to a
|
||||
* temporary file and then outputs it's contents to stdout.
|
||||
* If a resource pointer to a stream created by fopen() is passed
|
||||
* it will be used, but you have to close such stream by yourself.
|
||||
*
|
||||
* @param string|resource $filename The name of the file or stream where to save the OLE container.
|
||||
* @access public
|
||||
* @return mixed true on success
|
||||
*/
|
||||
public function save($filename)
|
||||
{
|
||||
// Initial Setting for saving
|
||||
$this->_BIG_BLOCK_SIZE = pow(2,
|
||||
((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9));
|
||||
$this->_SMALL_BLOCK_SIZE= pow(2,
|
||||
((isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE): 6));
|
||||
|
||||
if (is_resource($filename)) {
|
||||
$this->_FILEH_ = $filename;
|
||||
} else if ($filename == '-' || $filename == '') {
|
||||
if ($this->_tmp_dir === NULL)
|
||||
$this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir();
|
||||
$this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root");
|
||||
$this->_FILEH_ = fopen($this->_tmp_filename,"w+b");
|
||||
if ($this->_FILEH_ == false) {
|
||||
throw new PHPExcel_Writer_Exception("Can't create temporary file.");
|
||||
}
|
||||
} else {
|
||||
$this->_FILEH_ = fopen($filename, "wb");
|
||||
}
|
||||
if ($this->_FILEH_ == false) {
|
||||
throw new PHPExcel_Writer_Exception("Can't open $filename. It may be in use or protected.");
|
||||
}
|
||||
// Make an array of PPS's (for Save)
|
||||
$aList = array();
|
||||
PHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this));
|
||||
// calculate values for header
|
||||
list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo);
|
||||
// Save Header
|
||||
$this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);
|
||||
|
||||
// Make Small Data string (write SBD)
|
||||
$this->_data = $this->_makeSmallData($aList);
|
||||
|
||||
// Write BB
|
||||
$this->_saveBigData($iSBDcnt, $aList);
|
||||
// Write PPS
|
||||
$this->_savePps($aList);
|
||||
// Write Big Block Depot and BDList and Adding Header informations
|
||||
$this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);
|
||||
|
||||
if (!is_resource($filename)) {
|
||||
fclose($this->_FILEH_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate some numbers
|
||||
*
|
||||
* @access public
|
||||
* @param array $raList Reference to an array of PPS's
|
||||
* @return array The array of numbers
|
||||
*/
|
||||
public function _calcSize(&$raList)
|
||||
{
|
||||
// Calculate Basic Setting
|
||||
list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);
|
||||
$iSmallLen = 0;
|
||||
$iSBcnt = 0;
|
||||
$iCount = count($raList);
|
||||
for ($i = 0; $i < $iCount; ++$i) {
|
||||
if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) {
|
||||
$raList[$i]->Size = $raList[$i]->_DataLen();
|
||||
if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) {
|
||||
$iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
|
||||
+ (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
|
||||
} else {
|
||||
$iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
|
||||
(($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
$iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;
|
||||
$iSlCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE);
|
||||
$iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);
|
||||
$iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +
|
||||
(( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));
|
||||
$iCnt = count($raList);
|
||||
$iBdCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE;
|
||||
$iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));
|
||||
|
||||
return array($iSBDcnt, $iBBcnt, $iPPScnt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for caculating a magic value for block sizes
|
||||
*
|
||||
* @access public
|
||||
* @param integer $i2 The argument
|
||||
* @see save()
|
||||
* @return integer
|
||||
*/
|
||||
private static function _adjust2($i2)
|
||||
{
|
||||
$iWk = log($i2)/log(2);
|
||||
return ($iWk > floor($iWk))? floor($iWk)+1:$iWk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save OLE header
|
||||
*
|
||||
* @access public
|
||||
* @param integer $iSBDcnt
|
||||
* @param integer $iBBcnt
|
||||
* @param integer $iPPScnt
|
||||
*/
|
||||
public function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)
|
||||
{
|
||||
$FILE = $this->_FILEH_;
|
||||
|
||||
// Calculate Basic Setting
|
||||
$iBlCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
|
||||
$i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
|
||||
|
||||
$iBdExL = 0;
|
||||
$iAll = $iBBcnt + $iPPScnt + $iSBDcnt;
|
||||
$iAllW = $iAll;
|
||||
$iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
|
||||
$iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
|
||||
|
||||
// Calculate BD count
|
||||
if ($iBdCnt > $i1stBdL) {
|
||||
while (1) {
|
||||
++$iBdExL;
|
||||
++$iAllW;
|
||||
$iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);
|
||||
$iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);
|
||||
if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save Header
|
||||
fwrite($FILE,
|
||||
"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1"
|
||||
. "\x00\x00\x00\x00"
|
||||
. "\x00\x00\x00\x00"
|
||||
. "\x00\x00\x00\x00"
|
||||
. "\x00\x00\x00\x00"
|
||||
. pack("v", 0x3b)
|
||||
. pack("v", 0x03)
|
||||
. pack("v", -2)
|
||||
. pack("v", 9)
|
||||
. pack("v", 6)
|
||||
. pack("v", 0)
|
||||
. "\x00\x00\x00\x00"
|
||||
. "\x00\x00\x00\x00"
|
||||
. pack("V", $iBdCnt)
|
||||
. pack("V", $iBBcnt+$iSBDcnt) //ROOT START
|
||||
. pack("V", 0)
|
||||
. pack("V", 0x1000)
|
||||
. pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot
|
||||
. pack("V", $iSBDcnt)
|
||||
);
|
||||
// Extra BDList Start, Count
|
||||
if ($iBdCnt < $i1stBdL) {
|
||||
fwrite($FILE,
|
||||
pack("V", -2) // Extra BDList Start
|
||||
. pack("V", 0) // Extra BDList Count
|
||||
);
|
||||
} else {
|
||||
fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL));
|
||||
}
|
||||
|
||||
// BDList
|
||||
for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; ++$i) {
|
||||
fwrite($FILE, pack("V", $iAll+$i));
|
||||
}
|
||||
if ($i < $i1stBdL) {
|
||||
$jB = $i1stBdL - $i;
|
||||
for ($j = 0; $j < $jB; ++$j) {
|
||||
fwrite($FILE, (pack("V", -1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving big data (PPS's with data bigger than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL)
|
||||
*
|
||||
* @access public
|
||||
* @param integer $iStBlk
|
||||
* @param array &$raList Reference to array of PPS's
|
||||
*/
|
||||
public function _saveBigData($iStBlk, &$raList)
|
||||
{
|
||||
$FILE = $this->_FILEH_;
|
||||
|
||||
// cycle through PPS's
|
||||
$iCount = count($raList);
|
||||
for ($i = 0; $i < $iCount; ++$i) {
|
||||
if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) {
|
||||
$raList[$i]->Size = $raList[$i]->_DataLen();
|
||||
if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) ||
|
||||
(($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data)))
|
||||
{
|
||||
// Write Data
|
||||
//if (isset($raList[$i]->_PPS_FILE)) {
|
||||
// $iLen = 0;
|
||||
// fseek($raList[$i]->_PPS_FILE, 0); // To The Top
|
||||
// while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
|
||||
// $iLen += strlen($sBuff);
|
||||
// fwrite($FILE, $sBuff);
|
||||
// }
|
||||
//} else {
|
||||
fwrite($FILE, $raList[$i]->_data);
|
||||
//}
|
||||
|
||||
if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) {
|
||||
fwrite($FILE, str_repeat("\x00", $this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)));
|
||||
}
|
||||
// Set For PPS
|
||||
$raList[$i]->_StartBlock = $iStBlk;
|
||||
$iStBlk +=
|
||||
(floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +
|
||||
(($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));
|
||||
}
|
||||
// Close file for each PPS, and unlink it
|
||||
//if (isset($raList[$i]->_PPS_FILE)) {
|
||||
// fclose($raList[$i]->_PPS_FILE);
|
||||
// $raList[$i]->_PPS_FILE = null;
|
||||
// unlink($raList[$i]->_tmp_filename);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get small data (PPS's with data smaller than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL)
|
||||
*
|
||||
* @access public
|
||||
* @param array &$raList Reference to array of PPS's
|
||||
*/
|
||||
public function _makeSmallData(&$raList)
|
||||
{
|
||||
$sRes = '';
|
||||
$FILE = $this->_FILEH_;
|
||||
$iSmBlk = 0;
|
||||
|
||||
$iCount = count($raList);
|
||||
for ($i = 0; $i < $iCount; ++$i) {
|
||||
// Make SBD, small data string
|
||||
if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) {
|
||||
if ($raList[$i]->Size <= 0) {
|
||||
continue;
|
||||
}
|
||||
if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) {
|
||||
$iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)
|
||||
+ (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);
|
||||
// Add to SBD
|
||||
$jB = $iSmbCnt - 1;
|
||||
for ($j = 0; $j < $jB; ++$j) {
|
||||
fwrite($FILE, pack("V", $j+$iSmBlk+1));
|
||||
}
|
||||
fwrite($FILE, pack("V", -2));
|
||||
|
||||
//// Add to Data String(this will be written for RootEntry)
|
||||
//if ($raList[$i]->_PPS_FILE) {
|
||||
// fseek($raList[$i]->_PPS_FILE, 0); // To The Top
|
||||
// while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {
|
||||
// $sRes .= $sBuff;
|
||||
// }
|
||||
//} else {
|
||||
$sRes .= $raList[$i]->_data;
|
||||
//}
|
||||
if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) {
|
||||
$sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE));
|
||||
}
|
||||
// Set for PPS
|
||||
$raList[$i]->_StartBlock = $iSmBlk;
|
||||
$iSmBlk += $iSmbCnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
$iSbCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE);
|
||||
if ($iSmBlk % $iSbCnt) {
|
||||
$iB = $iSbCnt - ($iSmBlk % $iSbCnt);
|
||||
for ($i = 0; $i < $iB; ++$i) {
|
||||
fwrite($FILE, pack("V", -1));
|
||||
}
|
||||
}
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all the PPS's WKs
|
||||
*
|
||||
* @access public
|
||||
* @param array $raList Reference to an array with all PPS's
|
||||
*/
|
||||
public function _savePps(&$raList)
|
||||
{
|
||||
// Save each PPS WK
|
||||
$iC = count($raList);
|
||||
for ($i = 0; $i < $iC; ++$i) {
|
||||
fwrite($this->_FILEH_, $raList[$i]->_getPpsWk());
|
||||
}
|
||||
// Adjust for Block
|
||||
$iCnt = count($raList);
|
||||
$iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE;
|
||||
if ($iCnt % $iBCnt) {
|
||||
fwrite($this->_FILEH_, str_repeat("\x00",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving Big Block Depot
|
||||
*
|
||||
* @access public
|
||||
* @param integer $iSbdSize
|
||||
* @param integer $iBsize
|
||||
* @param integer $iPpsCnt
|
||||
*/
|
||||
public function _saveBbd($iSbdSize, $iBsize, $iPpsCnt)
|
||||
{
|
||||
$FILE = $this->_FILEH_;
|
||||
// Calculate Basic Setting
|
||||
$iBbCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
|
||||
$i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;
|
||||
|
||||
$iBdExL = 0;
|
||||
$iAll = $iBsize + $iPpsCnt + $iSbdSize;
|
||||
$iAllW = $iAll;
|
||||
$iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
|
||||
$iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
|
||||
// Calculate BD count
|
||||
if ($iBdCnt >$i1stBdL) {
|
||||
while (1) {
|
||||
++$iBdExL;
|
||||
++$iAllW;
|
||||
$iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);
|
||||
$iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);
|
||||
if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Making BD
|
||||
// Set for SBD
|
||||
if ($iSbdSize > 0) {
|
||||
for ($i = 0; $i < ($iSbdSize - 1); ++$i) {
|
||||
fwrite($FILE, pack("V", $i+1));
|
||||
}
|
||||
fwrite($FILE, pack("V", -2));
|
||||
}
|
||||
// Set for B
|
||||
for ($i = 0; $i < ($iBsize - 1); ++$i) {
|
||||
fwrite($FILE, pack("V", $i+$iSbdSize+1));
|
||||
}
|
||||
fwrite($FILE, pack("V", -2));
|
||||
|
||||
// Set for PPS
|
||||
for ($i = 0; $i < ($iPpsCnt - 1); ++$i) {
|
||||
fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1));
|
||||
}
|
||||
fwrite($FILE, pack("V", -2));
|
||||
// Set for BBD itself ( 0xFFFFFFFD : BBD)
|
||||
for ($i = 0; $i < $iBdCnt; ++$i) {
|
||||
fwrite($FILE, pack("V", 0xFFFFFFFD));
|
||||
}
|
||||
// Set for ExtraBDList
|
||||
for ($i = 0; $i < $iBdExL; ++$i) {
|
||||
fwrite($FILE, pack("V", 0xFFFFFFFC));
|
||||
}
|
||||
// Adjust for Block
|
||||
if (($iAllW + $iBdCnt) % $iBbCnt) {
|
||||
$iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt));
|
||||
for ($i = 0; $i < $iBlock; ++$i) {
|
||||
fwrite($FILE, pack("V", -1));
|
||||
}
|
||||
}
|
||||
// Extra BDList
|
||||
if ($iBdCnt > $i1stBdL) {
|
||||
$iN=0;
|
||||
$iNb=0;
|
||||
for ($i = $i1stBdL;$i < $iBdCnt; $i++, ++$iN) {
|
||||
if ($iN >= ($iBbCnt - 1)) {
|
||||
$iN = 0;
|
||||
++$iNb;
|
||||
fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb));
|
||||
}
|
||||
fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i));
|
||||
}
|
||||
if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) {
|
||||
$iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1));
|
||||
for ($i = 0; $i < $iB; ++$i) {
|
||||
fwrite($FILE, pack("V", -1));
|
||||
}
|
||||
}
|
||||
fwrite($FILE, pack("V", -2));
|
||||
}
|
||||
}
|
||||
}
|
317
extend/phpexcel/PHPExcel/Shared/OLERead.php
Executable file
317
extend/phpexcel/PHPExcel/Shared/OLERead.php
Executable file
@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
defined('IDENTIFIER_OLE') ||
|
||||
define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1));
|
||||
|
||||
class PHPExcel_Shared_OLERead {
|
||||
private $data = '';
|
||||
|
||||
// OLE identifier
|
||||
const IDENTIFIER_OLE = IDENTIFIER_OLE;
|
||||
|
||||
// Size of a sector = 512 bytes
|
||||
const BIG_BLOCK_SIZE = 0x200;
|
||||
|
||||
// Size of a short sector = 64 bytes
|
||||
const SMALL_BLOCK_SIZE = 0x40;
|
||||
|
||||
// Size of a directory entry always = 128 bytes
|
||||
const PROPERTY_STORAGE_BLOCK_SIZE = 0x80;
|
||||
|
||||
// Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams
|
||||
const SMALL_BLOCK_THRESHOLD = 0x1000;
|
||||
|
||||
// header offsets
|
||||
const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c;
|
||||
const ROOT_START_BLOCK_POS = 0x30;
|
||||
const SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c;
|
||||
const EXTENSION_BLOCK_POS = 0x44;
|
||||
const NUM_EXTENSION_BLOCK_POS = 0x48;
|
||||
const BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c;
|
||||
|
||||
// property storage offsets (directory offsets)
|
||||
const SIZE_OF_NAME_POS = 0x40;
|
||||
const TYPE_POS = 0x42;
|
||||
const START_BLOCK_POS = 0x74;
|
||||
const SIZE_POS = 0x78;
|
||||
|
||||
|
||||
|
||||
public $wrkbook = null;
|
||||
public $summaryInformation = null;
|
||||
public $documentSummaryInformation = null;
|
||||
|
||||
|
||||
/**
|
||||
* Read the file
|
||||
*
|
||||
* @param $sFileName string Filename
|
||||
* @throws PHPExcel_Reader_Exception
|
||||
*/
|
||||
public function read($sFileName)
|
||||
{
|
||||
// Check if file exists and is readable
|
||||
if(!is_readable($sFileName)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable.");
|
||||
}
|
||||
|
||||
// Get the file identifier
|
||||
// Don't bother reading the whole file until we know it's a valid OLE file
|
||||
$this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8);
|
||||
|
||||
// Check OLE identifier
|
||||
if ($this->data != self::IDENTIFIER_OLE) {
|
||||
throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file');
|
||||
}
|
||||
|
||||
// Get the file data
|
||||
$this->data = file_get_contents($sFileName);
|
||||
|
||||
// Total number of sectors used for the SAT
|
||||
$this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
|
||||
|
||||
// SecID of the first sector of the directory stream
|
||||
$this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);
|
||||
|
||||
// SecID of the first sector of the SSAT (or -2 if not extant)
|
||||
$this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);
|
||||
|
||||
// SecID of the first sector of the MSAT (or -2 if no additional sectors are used)
|
||||
$this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);
|
||||
|
||||
// Total number of sectors used by MSAT
|
||||
$this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);
|
||||
|
||||
$bigBlockDepotBlocks = array();
|
||||
$pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;
|
||||
|
||||
$bbdBlocks = $this->numBigBlockDepotBlocks;
|
||||
|
||||
if ($this->numExtensionBlocks != 0) {
|
||||
$bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $bbdBlocks; ++$i) {
|
||||
$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
|
||||
$pos += 4;
|
||||
}
|
||||
|
||||
for ($j = 0; $j < $this->numExtensionBlocks; ++$j) {
|
||||
$pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;
|
||||
$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);
|
||||
|
||||
for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {
|
||||
$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
|
||||
$pos += 4;
|
||||
}
|
||||
|
||||
$bbdBlocks += $blocksToRead;
|
||||
if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
|
||||
$this->extensionBlock = self::_GetInt4d($this->data, $pos);
|
||||
}
|
||||
}
|
||||
|
||||
$pos = 0;
|
||||
$this->bigBlockChain = '';
|
||||
$bbs = self::BIG_BLOCK_SIZE / 4;
|
||||
for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {
|
||||
$pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;
|
||||
|
||||
$this->bigBlockChain .= substr($this->data, $pos, 4*$bbs);
|
||||
$pos += 4*$bbs;
|
||||
}
|
||||
|
||||
$pos = 0;
|
||||
$sbdBlock = $this->sbdStartBlock;
|
||||
$this->smallBlockChain = '';
|
||||
while ($sbdBlock != -2) {
|
||||
$pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
|
||||
|
||||
$this->smallBlockChain .= substr($this->data, $pos, 4*$bbs);
|
||||
$pos += 4*$bbs;
|
||||
|
||||
$sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4);
|
||||
}
|
||||
|
||||
// read the directory stream
|
||||
$block = $this->rootStartBlock;
|
||||
$this->entry = $this->_readData($block);
|
||||
|
||||
$this->_readPropertySets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract binary stream data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStream($stream)
|
||||
{
|
||||
if ($stream === NULL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$streamData = '';
|
||||
|
||||
if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) {
|
||||
$rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']);
|
||||
|
||||
$block = $this->props[$stream]['startBlock'];
|
||||
|
||||
while ($block != -2) {
|
||||
$pos = $block * self::SMALL_BLOCK_SIZE;
|
||||
$streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);
|
||||
|
||||
$block = self::_GetInt4d($this->smallBlockChain, $block*4);
|
||||
}
|
||||
|
||||
return $streamData;
|
||||
} else {
|
||||
$numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE;
|
||||
if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) {
|
||||
++$numBlocks;
|
||||
}
|
||||
|
||||
if ($numBlocks == 0) return '';
|
||||
|
||||
$block = $this->props[$stream]['startBlock'];
|
||||
|
||||
while ($block != -2) {
|
||||
$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
|
||||
$streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
|
||||
$block = self::_GetInt4d($this->bigBlockChain, $block*4);
|
||||
}
|
||||
|
||||
return $streamData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a standard stream (by joining sectors using information from SAT)
|
||||
*
|
||||
* @param int $bl Sector ID where the stream starts
|
||||
* @return string Data for standard stream
|
||||
*/
|
||||
private function _readData($bl)
|
||||
{
|
||||
$block = $bl;
|
||||
$data = '';
|
||||
|
||||
while ($block != -2) {
|
||||
$pos = ($block + 1) * self::BIG_BLOCK_SIZE;
|
||||
$data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);
|
||||
$block = self::_GetInt4d($this->bigBlockChain, $block*4);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read entries in the directory stream.
|
||||
*/
|
||||
private function _readPropertySets() {
|
||||
$offset = 0;
|
||||
|
||||
// loop through entires, each entry is 128 bytes
|
||||
$entryLen = strlen($this->entry);
|
||||
while ($offset < $entryLen) {
|
||||
// entry data (128 bytes)
|
||||
$d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE);
|
||||
|
||||
// size in bytes of name
|
||||
$nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS+1]) << 8);
|
||||
|
||||
// type of entry
|
||||
$type = ord($d[self::TYPE_POS]);
|
||||
|
||||
// sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook)
|
||||
// sectorID of first sector of the short-stream container stream, if this entry is root entry
|
||||
$startBlock = self::_GetInt4d($d, self::START_BLOCK_POS);
|
||||
|
||||
$size = self::_GetInt4d($d, self::SIZE_POS);
|
||||
|
||||
$name = str_replace("\x00", "", substr($d,0,$nameSize));
|
||||
|
||||
|
||||
$this->props[] = array (
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'startBlock' => $startBlock,
|
||||
'size' => $size);
|
||||
|
||||
// tmp helper to simplify checks
|
||||
$upName = strtoupper($name);
|
||||
|
||||
// Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook)
|
||||
if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) {
|
||||
$this->wrkbook = count($this->props) - 1;
|
||||
}
|
||||
else if ( $upName === 'ROOT ENTRY' || $upName === 'R') {
|
||||
// Root entry
|
||||
$this->rootentry = count($this->props) - 1;
|
||||
}
|
||||
|
||||
// Summary information
|
||||
if ($name == chr(5) . 'SummaryInformation') {
|
||||
// echo 'Summary Information<br />';
|
||||
$this->summaryInformation = count($this->props) - 1;
|
||||
}
|
||||
|
||||
// Additional Document Summary information
|
||||
if ($name == chr(5) . 'DocumentSummaryInformation') {
|
||||
// echo 'Document Summary Information<br />';
|
||||
$this->documentSummaryInformation = count($this->props) - 1;
|
||||
}
|
||||
|
||||
$offset += self::PROPERTY_STORAGE_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read 4 bytes of data at specified position
|
||||
*
|
||||
* @param string $data
|
||||
* @param int $pos
|
||||
* @return int
|
||||
*/
|
||||
private static function _GetInt4d($data, $pos)
|
||||
{
|
||||
// FIX: represent numbers correctly on 64-bit system
|
||||
// http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
|
||||
// Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
|
||||
$_or_24 = ord($data[$pos + 3]);
|
||||
if ($_or_24 >= 128) {
|
||||
// negative number
|
||||
$_ord_24 = -abs((256 - $_or_24) << 24);
|
||||
} else {
|
||||
$_ord_24 = ($_or_24 & 127) << 24;
|
||||
}
|
||||
return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24;
|
||||
}
|
||||
|
||||
}
|
504
extend/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt
Executable file
504
extend/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt
Executable file
@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
5694
extend/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php
Executable file
5694
extend/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php
Executable file
File diff suppressed because it is too large
Load Diff
421
extend/phpexcel/PHPExcel/Shared/PCLZip/readme.txt
Executable file
421
extend/phpexcel/PHPExcel/Shared/PCLZip/readme.txt
Executable file
@ -0,0 +1,421 @@
|
||||
// --------------------------------------------------------------------------------
|
||||
// PclZip 2.8.2 - readme.txt
|
||||
// --------------------------------------------------------------------------------
|
||||
// License GNU/LGPL - August 2009
|
||||
// Vincent Blavet - vincent@phpconcept.net
|
||||
// http://www.phpconcept.net
|
||||
// --------------------------------------------------------------------------------
|
||||
// $Id: readme.txt,v 1.60 2009/09/30 20:35:21 vblavet Exp $
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
0 - Sommaire
|
||||
============
|
||||
1 - Introduction
|
||||
2 - What's new
|
||||
3 - Corrected bugs
|
||||
4 - Known bugs or limitations
|
||||
5 - License
|
||||
6 - Warning
|
||||
7 - Documentation
|
||||
8 - Author
|
||||
9 - Contribute
|
||||
|
||||
1 - Introduction
|
||||
================
|
||||
|
||||
PclZip is a library that allow you to manage a Zip archive.
|
||||
|
||||
Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip
|
||||
|
||||
2 - What's new
|
||||
==============
|
||||
|
||||
Version 2.8.2 :
|
||||
- PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with
|
||||
extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string
|
||||
can also be modified in the post-extract call back.
|
||||
**Bugs correction :
|
||||
- PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly
|
||||
- Remove use of eval() and do direct call to callback functions
|
||||
- Correct support of 64bits systems (Thanks to WordPress team)
|
||||
|
||||
Version 2.8.1 :
|
||||
- Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is
|
||||
deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will
|
||||
automatically replace it by PCLZIP_OPT_BY_PREG.
|
||||
|
||||
Version 2.8 :
|
||||
- Improve extraction of zip archive for large files by using temporary files
|
||||
This feature is working like the one defined in r2.7.
|
||||
Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF,
|
||||
PCLZIP_OPT_TEMP_FILE_THRESHOLD
|
||||
- Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto
|
||||
sense of temporary file use.
|
||||
- Bug correction : Reduce filepath in returned file list to remove ennoying
|
||||
'.//' preambule in file path.
|
||||
|
||||
Version 2.7 :
|
||||
- Improve creation of zip archive for large files :
|
||||
PclZip will now autosense the configured memory and use temporary files
|
||||
when large file is suspected.
|
||||
This feature can also ne triggered by manual options in create() and add()
|
||||
methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files,
|
||||
'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic,
|
||||
'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size
|
||||
threshold to use temporary files.
|
||||
Using "temporary files" rather than "memory" might take more time, but
|
||||
might give the ability to zip very large files :
|
||||
Tested on my win laptop with a 88Mo file :
|
||||
Zip "in-memory" : 18sec (max_execution_time=30, memory_limit=180Mo)
|
||||
Zip "tmporary-files" : 23sec (max_execution_time=30, memory_limit=30Mo)
|
||||
- Replace use of mktime() by time() to limit the E_STRICT error messages.
|
||||
- Bug correction : When adding files with full windows path (drive letter)
|
||||
PclZip is now working. Before, if the drive letter is not the default
|
||||
path, PclZip was not able to add the file.
|
||||
|
||||
Version 2.6 :
|
||||
- Code optimisation
|
||||
- New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to
|
||||
add a comment for a specific file. (Don't really know if this is usefull)
|
||||
- New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string
|
||||
as a file.
|
||||
- New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with
|
||||
a file.
|
||||
- Correct a bug. Files archived with a timestamp with 0h0m0s were extracted
|
||||
with current time
|
||||
- Add CRC value in the informations returned back for each file after an
|
||||
action.
|
||||
- Add missing closedir() statement.
|
||||
- When adding a folder, and removing the path of this folder, files were
|
||||
incorrectly added with a '/' at the beginning. Which means files are
|
||||
related to root in unix systems. Corrected.
|
||||
- Add conditional if before constant definition. This will allow users
|
||||
to redefine constants without changing the file, and then improve
|
||||
upgrade of pclzip code for new versions.
|
||||
|
||||
Version 2.5 :
|
||||
- Introduce the ability to add file/folder with individual properties (file descriptor).
|
||||
This gives for example the ability to change the filename of a zipped file.
|
||||
. Able to add files individually
|
||||
. Able to change full name
|
||||
. Able to change short name
|
||||
. Compatible with global options
|
||||
- New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME
|
||||
- New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE
|
||||
- Add a security control feature. PclZip can extract any file in any folder
|
||||
of a system. People may use this to upload a zip file and try to override
|
||||
a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the
|
||||
ability to forgive any directory transversal behavior.
|
||||
- New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path
|
||||
- New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION
|
||||
- Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend
|
||||
by current path (getcwd())
|
||||
|
||||
Version 2.4 :
|
||||
- Code improvment : try to speed up the code by removing unusefull call to pack()
|
||||
- Correct bug in delete() : delete() should be called with no argument. This was not
|
||||
the case in 2.3. This is corrected in 2.4.
|
||||
- Correct a bug in path_inclusion function. When the path has several '../../', the
|
||||
result was bad.
|
||||
- Add a check for magic_quotes_runtime configuration. If enabled, PclZip will
|
||||
disable it while working and det it back to its original value.
|
||||
This resolve a lots of bad formated archive errors.
|
||||
- Bug correction : PclZip now correctly unzip file in some specific situation,
|
||||
when compressed content has same size as uncompressed content.
|
||||
- Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH',
|
||||
directories are not any more created.
|
||||
- Code improvment : correct unclosed opendir(), better handling of . and .. in
|
||||
loops.
|
||||
|
||||
|
||||
Version 2.3 :
|
||||
- Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not
|
||||
give the same result in PHP4 and PHP5 ....
|
||||
|
||||
Version 2.2 :
|
||||
- Try development of PCLZIP_OPT_CRYPT .....
|
||||
However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers,
|
||||
the result (greater than a long) is not supported by PHP. Even the use of bcmath
|
||||
functions does not help. I did not find yet a solution ...;
|
||||
- Add missing '/' at end of directory entries
|
||||
- Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or
|
||||
error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION.
|
||||
- Corrected : Bad "version need to extract" field in local file header
|
||||
- Add private method privCheckFileHeaders() in order to check local and central
|
||||
file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives
|
||||
the ability to have a local file header without size, compressed size and crc filled.
|
||||
- Add a generic status 'error' for file status
|
||||
- Add control of compression type. PclZip only support deflate compression method.
|
||||
Before v2.2, PclZip does not check the compression method used in an archive while
|
||||
extracting. With v2.2 PclZip returns a new error status for a file using an unsupported
|
||||
compression method. New status is "unsupported_compression". New error code is
|
||||
PCLZIP_ERR_UNSUPPORTED_COMPRESSION.
|
||||
- Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files
|
||||
when errors like 'a folder with same name exists' or 'a newer file exists' or
|
||||
'a write protected file' exists, rather than set a status for the concerning file
|
||||
and resume the extract of the zip.
|
||||
- Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the
|
||||
replacement of the file, even if a newer version of the file exists.
|
||||
Note that today if a file with the same name already exists but is older it will be
|
||||
replaced by the extracted one.
|
||||
- Improve PclZipUtilOption()
|
||||
- Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central
|
||||
directory structure is the last data in the archive. Crypt encryption/decryption of
|
||||
zip archive put trailing 0 bytes after decryption. PclZip is now supporting this.
|
||||
|
||||
Version 2.1 :
|
||||
- Add the ability to abort the extraction by using a user callback function.
|
||||
The user can now return the value '2' in its callback which indicates to stop the
|
||||
extraction. For a pre call-back extract is stopped before the extration of the current
|
||||
file. For a post call back, the extraction is stopped after.
|
||||
- Add the ability to extract a file (or several files) directly in the standard output.
|
||||
This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract().
|
||||
- Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT,
|
||||
PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments
|
||||
in the zip archive.
|
||||
- When merging two archives, the comments are not any more lost, but merged, with a
|
||||
blank space separator.
|
||||
- Corrected bug : Files are not deleted when all files are asked to be deleted.
|
||||
- Corrected bug : Folders with name '0' made PclZip to abort the create or add feature.
|
||||
|
||||
|
||||
Version 2.0 :
|
||||
***** Warning : Some new features may break the backward compatibility for your scripts.
|
||||
Please carefully read the readme file.
|
||||
- Add the ability to delete by Index, name and regular expression. This feature is
|
||||
performed by the method delete(), which uses the optional parameters
|
||||
PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG.
|
||||
- Add the ability to extract by regular expression. To extract by regexp you must use the method
|
||||
extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG
|
||||
(depending if you want to use ereg() or preg_match() syntax) followed by the
|
||||
regular expression pattern.
|
||||
- Add the ability to extract by index, directly with the extract() method. This is a
|
||||
code improvment of the extractByIndex() method.
|
||||
- Add the ability to extract by name. To extract by name you must use the method
|
||||
extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to
|
||||
extract or an array of filenames to extract. To extract all a folder, use the folder
|
||||
name rather than the filename with a '/' at the end.
|
||||
- Add the ability to add files without compression. This is done with a new attribute
|
||||
which is PCLZIP_OPT_NO_COMPRESSION.
|
||||
- Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly
|
||||
in a string without using any file (or temporary file).
|
||||
- Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string.
|
||||
The default separator is now a comma (,) and not any more a blank space.
|
||||
THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with
|
||||
your script.
|
||||
- Improve algorythm performance by removing the use of temporary files when adding or
|
||||
extracting files in an archive.
|
||||
- Add (correct) detection of empty filename zipping. This can occurs when the removed
|
||||
path is the same
|
||||
as a zipped dir. The dir is not zipped (['status'] = filtered), only its content.
|
||||
- Add better support for windows paths (thanks for help from manus@manusfreedom.com).
|
||||
- Corrected bug : When the archive file already exists with size=0, the add() method
|
||||
fails. Corrected in 2.0.
|
||||
- Remove the use of OS_WINDOWS constant. Use php_uname() function rather.
|
||||
- Control the order of index ranges in extract by index feature.
|
||||
- Change the internal management of folders (better handling of internal flag).
|
||||
|
||||
|
||||
Version 1.3 :
|
||||
- Removing the double include check. This is now done by include_once() and require_once()
|
||||
PHP directives.
|
||||
- Changing the error handling mecanism : Remove the use of an external error library.
|
||||
The former PclError...() functions are replaced by internal equivalent methods.
|
||||
By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library.
|
||||
Introducing the use of constants for error codes rather than integer values. This will help
|
||||
in futur improvment.
|
||||
Introduction of error handling functions like errorCode(), errorName() and errorInfo().
|
||||
- Remove the deprecated use of calling function with arguments passed by reference.
|
||||
- Add the calling of extract(), extractByIndex(), create() and add() functions
|
||||
with variable options rather than fixed arguments.
|
||||
- Add the ability to remove all the file path while extracting or adding,
|
||||
without any need to specify the path to remove.
|
||||
This is available for extract(), extractByIndex(), create() and add() functionS by using
|
||||
the new variable options parameters :
|
||||
- PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct.
|
||||
- Ability to change the mode of a file after the extraction (chmod()).
|
||||
This is available for extract() and extractByIndex() functionS by using
|
||||
the new variable options parameters.
|
||||
- PCLZIP_OPT_SET_CHMOD : by setting the value of this option.
|
||||
- Ability to definition call-back options. These call-back will be called during the adding,
|
||||
or the extracting of file (extract(), extractByIndex(), create() and add() functions) :
|
||||
- PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user
|
||||
can trigerred the change the filename of the extracted file. The user can triggered the
|
||||
skip of the extraction. This is adding a 'skipped' status in the file list result value.
|
||||
- PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file.
|
||||
Nothing can be triggered from that point.
|
||||
- PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user
|
||||
can trigerred the change the stored filename of the added file. The user can triggered the
|
||||
skip of the add. This is adding a 'skipped' status in the file list result value.
|
||||
- PCLZIP_CB_POST_ADD : will be called after each add of a file.
|
||||
Nothing can be triggered from that point.
|
||||
- Two status are added in the file list returned as function result : skipped & filename_too_long
|
||||
'skipped' is used when a call-back function ask for skipping the file.
|
||||
'filename_too_long' is used while adding a file with a too long filename to archive (the file is
|
||||
not added)
|
||||
- Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into
|
||||
a directory.
|
||||
- Add a check of the presence of the archive file before some actions (like list, ...)
|
||||
- Add the initialisation of field "index" in header array. This means that by
|
||||
default index will be -1 when not explicitly set by the methods.
|
||||
|
||||
Version 1.2 :
|
||||
- Adding a duplicate function.
|
||||
- Adding a merge function. The merge function is a "quick merge" function,
|
||||
it just append the content of an archive at the end of the first one. There
|
||||
is no check for duplicate files or more recent files.
|
||||
- Improve the search of the central directory end.
|
||||
|
||||
Version 1.1.2 :
|
||||
|
||||
- Changing the license of PclZip. PclZip is now released under the GNU / LGPL license
|
||||
(see License section).
|
||||
- Adding the optional support of a static temporary directory. You will need to configure
|
||||
the constant PCLZIP_TEMPORARY_DIR if you want to use this feature.
|
||||
- Improving the rename() function. In some cases rename() does not work (different
|
||||
Filesystems), so it will be replaced by a copy() + unlink() functions.
|
||||
|
||||
Version 1.1.1 :
|
||||
|
||||
- Maintenance release, no new feature.
|
||||
|
||||
Version 1.1 :
|
||||
|
||||
- New method Add() : adding files in the archive
|
||||
- New method ExtractByIndex() : partial extract of the archive, files are identified by
|
||||
their index in the archive
|
||||
- New method DeleteByIndex() : delete some files/folder entries from the archive,
|
||||
files are identified by their index in the archive.
|
||||
- Adding a test of the zlib extension presence. If not present abort the script.
|
||||
|
||||
Version 1.0.1 :
|
||||
|
||||
- No new feature
|
||||
|
||||
|
||||
3 - Corrected bugs
|
||||
==================
|
||||
|
||||
Corrected in Version 2.0 :
|
||||
- Corrected : During an extraction, if a call-back fucntion is used and try to skip
|
||||
a file, all the extraction process is stopped.
|
||||
|
||||
Corrected in Version 1.3 :
|
||||
- Corrected : Support of static synopsis for method extract() is broken.
|
||||
- Corrected : invalid size of archive content field (0xFF) should be (0xFFFF).
|
||||
- Corrected : When an extract is done with a remove_path parameter, the entry for
|
||||
the directory with exactly the same path is not skipped/filtered.
|
||||
- Corrected : extractByIndex() and deleteByIndex() were not managing index in the
|
||||
right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This
|
||||
is due to a sort of the index resulting table that puts 11 before 3-5 (sort on
|
||||
string and not interger). The sort is temporarilly removed, this means that
|
||||
you must provide a sorted list of index ranges.
|
||||
|
||||
Corrected in Version 1.2 :
|
||||
|
||||
- Nothing.
|
||||
|
||||
Corrected in Version 1.1.2 :
|
||||
|
||||
- Corrected : Winzip is unable to delete or add new files in a PclZip created archives.
|
||||
|
||||
Corrected in Version 1.1.1 :
|
||||
|
||||
- Corrected : When archived file is not compressed (0% compression), the
|
||||
extract method fails.
|
||||
|
||||
Corrected in Version 1.1 :
|
||||
|
||||
- Corrected : Adding a complete tree of folder may result in a bad archive
|
||||
creation.
|
||||
|
||||
Corrected in Version 1.0.1 :
|
||||
|
||||
- Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).
|
||||
|
||||
|
||||
4 - Known bugs or limitations
|
||||
=============================
|
||||
|
||||
Please publish bugs reports in SourceForge :
|
||||
http://sourceforge.net/tracker/?group_id=40254&atid=427564
|
||||
|
||||
In Version 2.x :
|
||||
- PclZip does only support file uncompressed or compressed with deflate (compression method 8)
|
||||
- PclZip does not support password protected zip archive
|
||||
- Some concern were seen when changing mtime of a file while archiving.
|
||||
Seems to be linked to Daylight Saving Time (PclTest_changing_mtime).
|
||||
|
||||
In Version 1.2 :
|
||||
|
||||
- merge() methods does not check for duplicate files or last date of modifications.
|
||||
|
||||
In Version 1.1 :
|
||||
|
||||
- Limitation : Using 'extract' fields in the file header in the zip archive is not supported.
|
||||
- WinZip is unable to delete a single file in a PclZip created archive. It is also unable to
|
||||
add a file in a PclZip created archive. (Corrected in v.1.2)
|
||||
|
||||
In Version 1.0.1 :
|
||||
|
||||
- Adding a complete tree of folder may result in a bad archive
|
||||
creation. (Corrected in V.1.1).
|
||||
- Path given to methods must be in the unix format (/) and not the Windows format (\).
|
||||
Workaround : Use only / directory separators.
|
||||
- PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz
|
||||
added suffix. Files with these names may already exist and may be overwritten.
|
||||
Workaround : none.
|
||||
- PclZip does not check if the zlib extension is present. If it is absent, the zip
|
||||
file is not created and the lib abort without warning.
|
||||
Workaround : enable the zlib extension on the php install
|
||||
|
||||
In Version 1.0 :
|
||||
|
||||
- Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).
|
||||
(Corrected in v.1.0.1)
|
||||
- Limitation : Multi-disk zip archive are not supported.
|
||||
|
||||
|
||||
5 - License
|
||||
===========
|
||||
|
||||
Since version 1.1.2, PclZip Library is released under GNU/LGPL license.
|
||||
This library is free, so you can use it at no cost.
|
||||
|
||||
HOWEVER, if you release a script, an application, a library or any kind of
|
||||
code using PclZip library (or a part of it), YOU MUST :
|
||||
- Indicate in the documentation (or a readme file), that your work
|
||||
uses PclZip Library, and make a reference to the author and the web site
|
||||
http://www.phpconcept.net
|
||||
- Gives the ability to the final user to update the PclZip libary.
|
||||
|
||||
I will also appreciate that you send me a mail (vincent@phpconcept.net), just to
|
||||
be aware that someone is using PclZip.
|
||||
|
||||
For more information about GNU/LGPL license : http://www.gnu.org
|
||||
|
||||
6 - Warning
|
||||
=================
|
||||
|
||||
This library and the associated files are non commercial, non professional work.
|
||||
It should not have unexpected results. However if any damage is caused by this software
|
||||
the author can not be responsible.
|
||||
The use of this software is at the risk of the user.
|
||||
|
||||
7 - Documentation
|
||||
=================
|
||||
PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php
|
||||
A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/
|
||||
|
||||
8 - Author
|
||||
==========
|
||||
|
||||
This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time.
|
||||
|
||||
9 - Contribute
|
||||
==============
|
||||
If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net.
|
||||
If you can help in financing PhpConcept hosting service, please go to
|
||||
http://www.phpconcept.net/soutien.php
|
66
extend/phpexcel/PHPExcel/Shared/PasswordHasher.php
Executable file
66
extend/phpexcel/PHPExcel/Shared/PasswordHasher.php
Executable file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_PasswordHasher
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_PasswordHasher
|
||||
{
|
||||
/**
|
||||
* Create a password hash from a given string.
|
||||
*
|
||||
* This method is based on the algorithm provided by
|
||||
* Daniel Rentz of OpenOffice and the PEAR package
|
||||
* Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>.
|
||||
*
|
||||
* @param string $pPassword Password to hash
|
||||
* @return string Hashed password
|
||||
*/
|
||||
public static function hashPassword($pPassword = '') {
|
||||
$password = 0x0000;
|
||||
$charPos = 1; // char position
|
||||
|
||||
// split the plain text password in its component characters
|
||||
$chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY);
|
||||
foreach ($chars as $char) {
|
||||
$value = ord($char) << $charPos++; // shifted ASCII value
|
||||
$rotated_bits = $value >> 15; // rotated bits beyond bit 15
|
||||
$value &= 0x7fff; // first 15 bits
|
||||
$password ^= ($value | $rotated_bits);
|
||||
}
|
||||
|
||||
$password ^= strlen($pPassword);
|
||||
$password ^= 0xCE4B;
|
||||
|
||||
return(strtoupper(dechex($password)));
|
||||
}
|
||||
}
|
776
extend/phpexcel/PHPExcel/Shared/String.php
Executable file
776
extend/phpexcel/PHPExcel/Shared/String.php
Executable file
@ -0,0 +1,776 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_String
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_String
|
||||
{
|
||||
/** Constants */
|
||||
/** Regular Expressions */
|
||||
// Fraction
|
||||
const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)';
|
||||
|
||||
|
||||
/**
|
||||
* Control characters array
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private static $_controlCharacters = array();
|
||||
|
||||
/**
|
||||
* SYLK Characters array
|
||||
*
|
||||
* $var array
|
||||
*/
|
||||
private static $_SYLKCharacters = array();
|
||||
|
||||
/**
|
||||
* Decimal separator
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_decimalSeparator;
|
||||
|
||||
/**
|
||||
* Thousands separator
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_thousandsSeparator;
|
||||
|
||||
/**
|
||||
* Currency code
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $_currencyCode;
|
||||
|
||||
/**
|
||||
* Is mbstring extension avalable?
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $_isMbstringEnabled;
|
||||
|
||||
/**
|
||||
* Is iconv extension avalable?
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $_isIconvEnabled;
|
||||
|
||||
/**
|
||||
* Build control characters array
|
||||
*/
|
||||
private static function _buildControlCharacters() {
|
||||
for ($i = 0; $i <= 31; ++$i) {
|
||||
if ($i != 9 && $i != 10 && $i != 13) {
|
||||
$find = '_x' . sprintf('%04s' , strtoupper(dechex($i))) . '_';
|
||||
$replace = chr($i);
|
||||
self::$_controlCharacters[$find] = $replace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SYLK characters array
|
||||
*/
|
||||
private static function _buildSYLKCharacters()
|
||||
{
|
||||
self::$_SYLKCharacters = array(
|
||||
"\x1B 0" => chr(0),
|
||||
"\x1B 1" => chr(1),
|
||||
"\x1B 2" => chr(2),
|
||||
"\x1B 3" => chr(3),
|
||||
"\x1B 4" => chr(4),
|
||||
"\x1B 5" => chr(5),
|
||||
"\x1B 6" => chr(6),
|
||||
"\x1B 7" => chr(7),
|
||||
"\x1B 8" => chr(8),
|
||||
"\x1B 9" => chr(9),
|
||||
"\x1B :" => chr(10),
|
||||
"\x1B ;" => chr(11),
|
||||
"\x1B <" => chr(12),
|
||||
"\x1B :" => chr(13),
|
||||
"\x1B >" => chr(14),
|
||||
"\x1B ?" => chr(15),
|
||||
"\x1B!0" => chr(16),
|
||||
"\x1B!1" => chr(17),
|
||||
"\x1B!2" => chr(18),
|
||||
"\x1B!3" => chr(19),
|
||||
"\x1B!4" => chr(20),
|
||||
"\x1B!5" => chr(21),
|
||||
"\x1B!6" => chr(22),
|
||||
"\x1B!7" => chr(23),
|
||||
"\x1B!8" => chr(24),
|
||||
"\x1B!9" => chr(25),
|
||||
"\x1B!:" => chr(26),
|
||||
"\x1B!;" => chr(27),
|
||||
"\x1B!<" => chr(28),
|
||||
"\x1B!=" => chr(29),
|
||||
"\x1B!>" => chr(30),
|
||||
"\x1B!?" => chr(31),
|
||||
"\x1B'?" => chr(127),
|
||||
"\x1B(0" => '€', // 128 in CP1252
|
||||
"\x1B(2" => '‚', // 130 in CP1252
|
||||
"\x1B(3" => 'ƒ', // 131 in CP1252
|
||||
"\x1B(4" => '„', // 132 in CP1252
|
||||
"\x1B(5" => '…', // 133 in CP1252
|
||||
"\x1B(6" => '†', // 134 in CP1252
|
||||
"\x1B(7" => '‡', // 135 in CP1252
|
||||
"\x1B(8" => 'ˆ', // 136 in CP1252
|
||||
"\x1B(9" => '‰', // 137 in CP1252
|
||||
"\x1B(:" => 'Š', // 138 in CP1252
|
||||
"\x1B(;" => '‹', // 139 in CP1252
|
||||
"\x1BNj" => 'Œ', // 140 in CP1252
|
||||
"\x1B(>" => 'Ž', // 142 in CP1252
|
||||
"\x1B)1" => '‘', // 145 in CP1252
|
||||
"\x1B)2" => '’', // 146 in CP1252
|
||||
"\x1B)3" => '“', // 147 in CP1252
|
||||
"\x1B)4" => '”', // 148 in CP1252
|
||||
"\x1B)5" => '•', // 149 in CP1252
|
||||
"\x1B)6" => '–', // 150 in CP1252
|
||||
"\x1B)7" => '—', // 151 in CP1252
|
||||
"\x1B)8" => '˜', // 152 in CP1252
|
||||
"\x1B)9" => '™', // 153 in CP1252
|
||||
"\x1B):" => 'š', // 154 in CP1252
|
||||
"\x1B);" => '›', // 155 in CP1252
|
||||
"\x1BNz" => 'œ', // 156 in CP1252
|
||||
"\x1B)>" => 'ž', // 158 in CP1252
|
||||
"\x1B)?" => 'Ÿ', // 159 in CP1252
|
||||
"\x1B*0" => ' ', // 160 in CP1252
|
||||
"\x1BN!" => '¡', // 161 in CP1252
|
||||
"\x1BN\"" => '¢', // 162 in CP1252
|
||||
"\x1BN#" => '£', // 163 in CP1252
|
||||
"\x1BN(" => '¤', // 164 in CP1252
|
||||
"\x1BN%" => '¥', // 165 in CP1252
|
||||
"\x1B*6" => '¦', // 166 in CP1252
|
||||
"\x1BN'" => '§', // 167 in CP1252
|
||||
"\x1BNH " => '¨', // 168 in CP1252
|
||||
"\x1BNS" => '©', // 169 in CP1252
|
||||
"\x1BNc" => 'ª', // 170 in CP1252
|
||||
"\x1BN+" => '«', // 171 in CP1252
|
||||
"\x1B*<" => '¬', // 172 in CP1252
|
||||
"\x1B*=" => '', // 173 in CP1252
|
||||
"\x1BNR" => '®', // 174 in CP1252
|
||||
"\x1B*?" => '¯', // 175 in CP1252
|
||||
"\x1BN0" => '°', // 176 in CP1252
|
||||
"\x1BN1" => '±', // 177 in CP1252
|
||||
"\x1BN2" => '²', // 178 in CP1252
|
||||
"\x1BN3" => '³', // 179 in CP1252
|
||||
"\x1BNB " => '´', // 180 in CP1252
|
||||
"\x1BN5" => 'µ', // 181 in CP1252
|
||||
"\x1BN6" => '¶', // 182 in CP1252
|
||||
"\x1BN7" => '·', // 183 in CP1252
|
||||
"\x1B+8" => '¸', // 184 in CP1252
|
||||
"\x1BNQ" => '¹', // 185 in CP1252
|
||||
"\x1BNk" => 'º', // 186 in CP1252
|
||||
"\x1BN;" => '»', // 187 in CP1252
|
||||
"\x1BN<" => '¼', // 188 in CP1252
|
||||
"\x1BN=" => '½', // 189 in CP1252
|
||||
"\x1BN>" => '¾', // 190 in CP1252
|
||||
"\x1BN?" => '¿', // 191 in CP1252
|
||||
"\x1BNAA" => 'À', // 192 in CP1252
|
||||
"\x1BNBA" => 'Á', // 193 in CP1252
|
||||
"\x1BNCA" => 'Â', // 194 in CP1252
|
||||
"\x1BNDA" => 'Ã', // 195 in CP1252
|
||||
"\x1BNHA" => 'Ä', // 196 in CP1252
|
||||
"\x1BNJA" => 'Å', // 197 in CP1252
|
||||
"\x1BNa" => 'Æ', // 198 in CP1252
|
||||
"\x1BNKC" => 'Ç', // 199 in CP1252
|
||||
"\x1BNAE" => 'È', // 200 in CP1252
|
||||
"\x1BNBE" => 'É', // 201 in CP1252
|
||||
"\x1BNCE" => 'Ê', // 202 in CP1252
|
||||
"\x1BNHE" => 'Ë', // 203 in CP1252
|
||||
"\x1BNAI" => 'Ì', // 204 in CP1252
|
||||
"\x1BNBI" => 'Í', // 205 in CP1252
|
||||
"\x1BNCI" => 'Î', // 206 in CP1252
|
||||
"\x1BNHI" => 'Ï', // 207 in CP1252
|
||||
"\x1BNb" => 'Ð', // 208 in CP1252
|
||||
"\x1BNDN" => 'Ñ', // 209 in CP1252
|
||||
"\x1BNAO" => 'Ò', // 210 in CP1252
|
||||
"\x1BNBO" => 'Ó', // 211 in CP1252
|
||||
"\x1BNCO" => 'Ô', // 212 in CP1252
|
||||
"\x1BNDO" => 'Õ', // 213 in CP1252
|
||||
"\x1BNHO" => 'Ö', // 214 in CP1252
|
||||
"\x1B-7" => '×', // 215 in CP1252
|
||||
"\x1BNi" => 'Ø', // 216 in CP1252
|
||||
"\x1BNAU" => 'Ù', // 217 in CP1252
|
||||
"\x1BNBU" => 'Ú', // 218 in CP1252
|
||||
"\x1BNCU" => 'Û', // 219 in CP1252
|
||||
"\x1BNHU" => 'Ü', // 220 in CP1252
|
||||
"\x1B-=" => 'Ý', // 221 in CP1252
|
||||
"\x1BNl" => 'Þ', // 222 in CP1252
|
||||
"\x1BN{" => 'ß', // 223 in CP1252
|
||||
"\x1BNAa" => 'à', // 224 in CP1252
|
||||
"\x1BNBa" => 'á', // 225 in CP1252
|
||||
"\x1BNCa" => 'â', // 226 in CP1252
|
||||
"\x1BNDa" => 'ã', // 227 in CP1252
|
||||
"\x1BNHa" => 'ä', // 228 in CP1252
|
||||
"\x1BNJa" => 'å', // 229 in CP1252
|
||||
"\x1BNq" => 'æ', // 230 in CP1252
|
||||
"\x1BNKc" => 'ç', // 231 in CP1252
|
||||
"\x1BNAe" => 'è', // 232 in CP1252
|
||||
"\x1BNBe" => 'é', // 233 in CP1252
|
||||
"\x1BNCe" => 'ê', // 234 in CP1252
|
||||
"\x1BNHe" => 'ë', // 235 in CP1252
|
||||
"\x1BNAi" => 'ì', // 236 in CP1252
|
||||
"\x1BNBi" => 'í', // 237 in CP1252
|
||||
"\x1BNCi" => 'î', // 238 in CP1252
|
||||
"\x1BNHi" => 'ï', // 239 in CP1252
|
||||
"\x1BNs" => 'ð', // 240 in CP1252
|
||||
"\x1BNDn" => 'ñ', // 241 in CP1252
|
||||
"\x1BNAo" => 'ò', // 242 in CP1252
|
||||
"\x1BNBo" => 'ó', // 243 in CP1252
|
||||
"\x1BNCo" => 'ô', // 244 in CP1252
|
||||
"\x1BNDo" => 'õ', // 245 in CP1252
|
||||
"\x1BNHo" => 'ö', // 246 in CP1252
|
||||
"\x1B/7" => '÷', // 247 in CP1252
|
||||
"\x1BNy" => 'ø', // 248 in CP1252
|
||||
"\x1BNAu" => 'ù', // 249 in CP1252
|
||||
"\x1BNBu" => 'ú', // 250 in CP1252
|
||||
"\x1BNCu" => 'û', // 251 in CP1252
|
||||
"\x1BNHu" => 'ü', // 252 in CP1252
|
||||
"\x1B/=" => 'ý', // 253 in CP1252
|
||||
"\x1BN|" => 'þ', // 254 in CP1252
|
||||
"\x1BNHy" => 'ÿ', // 255 in CP1252
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether mbstring extension is available
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function getIsMbstringEnabled()
|
||||
{
|
||||
if (isset(self::$_isMbstringEnabled)) {
|
||||
return self::$_isMbstringEnabled;
|
||||
}
|
||||
|
||||
self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ?
|
||||
true : false;
|
||||
|
||||
return self::$_isMbstringEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether iconv extension is available
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function getIsIconvEnabled()
|
||||
{
|
||||
if (isset(self::$_isIconvEnabled)) {
|
||||
return self::$_isIconvEnabled;
|
||||
}
|
||||
|
||||
// Fail if iconv doesn't exist
|
||||
if (!function_exists('iconv')) {
|
||||
self::$_isIconvEnabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false,
|
||||
if (!@iconv('UTF-8', 'UTF-16LE', 'x')) {
|
||||
self::$_isIconvEnabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0
|
||||
// we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773)
|
||||
if (!@iconv_substr('A', 0, 1, 'UTF-8')) {
|
||||
self::$_isIconvEnabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// CUSTOM: IBM AIX iconv() does not work
|
||||
if ( defined('PHP_OS') && @stristr(PHP_OS, 'AIX')
|
||||
&& defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0)
|
||||
&& defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0) )
|
||||
{
|
||||
self::$_isIconvEnabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we reach here no problems were detected with iconv
|
||||
self::$_isIconvEnabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function buildCharacterSets() {
|
||||
if(empty(self::$_controlCharacters)) {
|
||||
self::_buildControlCharacters();
|
||||
}
|
||||
if(empty(self::$_SYLKCharacters)) {
|
||||
self::_buildSYLKCharacters();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from OpenXML escaped control character to PHP control character
|
||||
*
|
||||
* Excel 2007 team:
|
||||
* ----------------
|
||||
* That's correct, control characters are stored directly in the shared-strings table.
|
||||
* We do encode characters that cannot be represented in XML using the following escape sequence:
|
||||
* _xHHHH_ where H represents a hexadecimal character in the character's value...
|
||||
* So you could end up with something like _x0008_ in a string (either in a cell value (<v>)
|
||||
* element or in the shared string <t> element.
|
||||
*
|
||||
* @param string $value Value to unescape
|
||||
* @return string
|
||||
*/
|
||||
public static function ControlCharacterOOXML2PHP($value = '') {
|
||||
return str_replace( array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from PHP control character to OpenXML escaped control character
|
||||
*
|
||||
* Excel 2007 team:
|
||||
* ----------------
|
||||
* That's correct, control characters are stored directly in the shared-strings table.
|
||||
* We do encode characters that cannot be represented in XML using the following escape sequence:
|
||||
* _xHHHH_ where H represents a hexadecimal character in the character's value...
|
||||
* So you could end up with something like _x0008_ in a string (either in a cell value (<v>)
|
||||
* element or in the shared string <t> element.
|
||||
*
|
||||
* @param string $value Value to escape
|
||||
* @return string
|
||||
*/
|
||||
public static function ControlCharacterPHP2OOXML($value = '') {
|
||||
return str_replace( array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function SanitizeUTF8($value)
|
||||
{
|
||||
if (self::getIsIconvEnabled()) {
|
||||
$value = @iconv('UTF-8', 'UTF-8', $value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (self::getIsMbstringEnabled()) {
|
||||
$value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
|
||||
return $value;
|
||||
}
|
||||
|
||||
// else, no conversion
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string contains UTF8 data
|
||||
*
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
public static function IsUTF8($value = '') {
|
||||
return $string === '' || preg_match('/^./su', $string) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a numeric value as a string for output in various output writers forcing
|
||||
* point as decimal separator in case locale is other than English.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
public static function FormatNumber($value) {
|
||||
if (is_float($value)) {
|
||||
return str_replace(',', '.', $value);
|
||||
}
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length)
|
||||
* Writes the string using uncompressed notation, no rich text, no Asian phonetics
|
||||
* If mbstring extension is not available, ASCII is assumed, and compressed notation is used
|
||||
* although this will give wrong results for non-ASCII strings
|
||||
* see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3
|
||||
*
|
||||
* @param string $value UTF-8 encoded string
|
||||
* @param mixed[] $arrcRuns Details of rich text runs in $value
|
||||
* @return string
|
||||
*/
|
||||
public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array())
|
||||
{
|
||||
// character count
|
||||
$ln = self::CountCharacters($value, 'UTF-8');
|
||||
// option flags
|
||||
if(empty($arrcRuns)){
|
||||
$opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ?
|
||||
0x0001 : 0x0000;
|
||||
$data = pack('CC', $ln, $opt);
|
||||
// characters
|
||||
$data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8');
|
||||
}
|
||||
else {
|
||||
$data = pack('vC', $ln, 0x09);
|
||||
$data .= pack('v', count($arrcRuns));
|
||||
// characters
|
||||
$data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8');
|
||||
foreach ($arrcRuns as $cRun){
|
||||
$data .= pack('v', $cRun['strlen']);
|
||||
$data .= pack('v', $cRun['fontidx']);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length)
|
||||
* Writes the string using uncompressed notation, no rich text, no Asian phonetics
|
||||
* If mbstring extension is not available, ASCII is assumed, and compressed notation is used
|
||||
* although this will give wrong results for non-ASCII strings
|
||||
* see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3
|
||||
*
|
||||
* @param string $value UTF-8 encoded string
|
||||
* @return string
|
||||
*/
|
||||
public static function UTF8toBIFF8UnicodeLong($value)
|
||||
{
|
||||
// character count
|
||||
$ln = self::CountCharacters($value, 'UTF-8');
|
||||
|
||||
// option flags
|
||||
$opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ?
|
||||
0x0001 : 0x0000;
|
||||
|
||||
// characters
|
||||
$chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8');
|
||||
|
||||
$data = pack('vC', $ln, $opt) . $chars;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string from one encoding to another. First try mbstring, then iconv, finally strlen
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $to Encoding to convert to, e.g. 'UTF-8'
|
||||
* @param string $from Encoding to convert from, e.g. 'UTF-16LE'
|
||||
* @return string
|
||||
*/
|
||||
public static function ConvertEncoding($value, $to, $from)
|
||||
{
|
||||
if (self::getIsIconvEnabled()) {
|
||||
return iconv($from, $to, $value);
|
||||
}
|
||||
|
||||
if (self::getIsMbstringEnabled()) {
|
||||
return mb_convert_encoding($value, $to, $from);
|
||||
}
|
||||
|
||||
if($from == 'UTF-16LE'){
|
||||
return self::utf16_decode($value, false);
|
||||
}else if($from == 'UTF-16BE'){
|
||||
return self::utf16_decode($value);
|
||||
}
|
||||
// else, no conversion
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode UTF-16 encoded strings.
|
||||
*
|
||||
* Can handle both BOM'ed data and un-BOM'ed data.
|
||||
* Assumes Big-Endian byte order if no BOM is available.
|
||||
* This function was taken from http://php.net/manual/en/function.utf8-decode.php
|
||||
* and $bom_be parameter added.
|
||||
*
|
||||
* @param string $str UTF-16 encoded data to decode.
|
||||
* @return string UTF-8 / ISO encoded data.
|
||||
* @access public
|
||||
* @version 0.2 / 2010-05-13
|
||||
* @author Rasmus Andersson {@link http://rasmusandersson.se/}
|
||||
* @author vadik56
|
||||
*/
|
||||
public static function utf16_decode($str, $bom_be = TRUE) {
|
||||
if( strlen($str) < 2 ) return $str;
|
||||
$c0 = ord($str{0});
|
||||
$c1 = ord($str{1});
|
||||
if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); }
|
||||
elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; }
|
||||
$len = strlen($str);
|
||||
$newstr = '';
|
||||
for($i=0;$i<$len;$i+=2) {
|
||||
if( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); }
|
||||
else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); }
|
||||
$newstr .= ($val == 0x228) ? "\n" : chr($val);
|
||||
}
|
||||
return $newstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get character count. First try mbstring, then iconv, finally strlen
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $enc Encoding
|
||||
* @return int Character count
|
||||
*/
|
||||
public static function CountCharacters($value, $enc = 'UTF-8')
|
||||
{
|
||||
if (self::getIsMbstringEnabled()) {
|
||||
return mb_strlen($value, $enc);
|
||||
}
|
||||
|
||||
if (self::getIsIconvEnabled()) {
|
||||
return iconv_strlen($value, $enc);
|
||||
}
|
||||
|
||||
// else strlen
|
||||
return strlen($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen
|
||||
*
|
||||
* @param string $pValue UTF-8 encoded string
|
||||
* @param int $pStart Start offset
|
||||
* @param int $pLength Maximum number of characters in substring
|
||||
* @return string
|
||||
*/
|
||||
public static function Substring($pValue = '', $pStart = 0, $pLength = 0)
|
||||
{
|
||||
if (self::getIsMbstringEnabled()) {
|
||||
return mb_substr($pValue, $pStart, $pLength, 'UTF-8');
|
||||
}
|
||||
|
||||
if (self::getIsIconvEnabled()) {
|
||||
return iconv_substr($pValue, $pStart, $pLength, 'UTF-8');
|
||||
}
|
||||
|
||||
// else substr
|
||||
return substr($pValue, $pStart, $pLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 encoded string to upper case
|
||||
*
|
||||
* @param string $pValue UTF-8 encoded string
|
||||
* @return string
|
||||
*/
|
||||
public static function StrToUpper($pValue = '')
|
||||
{
|
||||
if (function_exists('mb_convert_case')) {
|
||||
return mb_convert_case($pValue, MB_CASE_UPPER, "UTF-8");
|
||||
}
|
||||
return strtoupper($pValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 encoded string to lower case
|
||||
*
|
||||
* @param string $pValue UTF-8 encoded string
|
||||
* @return string
|
||||
*/
|
||||
public static function StrToLower($pValue = '')
|
||||
{
|
||||
if (function_exists('mb_convert_case')) {
|
||||
return mb_convert_case($pValue, MB_CASE_LOWER, "UTF-8");
|
||||
}
|
||||
return strtolower($pValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 encoded string to title/proper case
|
||||
* (uppercase every first character in each word, lower case all other characters)
|
||||
*
|
||||
* @param string $pValue UTF-8 encoded string
|
||||
* @return string
|
||||
*/
|
||||
public static function StrToTitle($pValue = '')
|
||||
{
|
||||
if (function_exists('mb_convert_case')) {
|
||||
return mb_convert_case($pValue, MB_CASE_TITLE, "UTF-8");
|
||||
}
|
||||
return ucwords($pValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify whether a string contains a fractional numeric value,
|
||||
* and convert it to a numeric if it is
|
||||
*
|
||||
* @param string &$operand string value to test
|
||||
* @return boolean
|
||||
*/
|
||||
public static function convertToNumberIfFraction(&$operand) {
|
||||
if (preg_match('/^'.self::STRING_REGEXP_FRACTION.'$/i', $operand, $match)) {
|
||||
$sign = ($match[1] == '-') ? '-' : '+';
|
||||
$fractionFormula = '='.$sign.$match[2].$sign.$match[3];
|
||||
$operand = PHPExcel_Calculation::getInstance()->_calculateFormulaValue($fractionFormula);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} // function convertToNumberIfFraction()
|
||||
|
||||
/**
|
||||
* Get the decimal separator. If it has not yet been set explicitly, try to obtain number
|
||||
* formatting information from locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDecimalSeparator()
|
||||
{
|
||||
if (!isset(self::$_decimalSeparator)) {
|
||||
$localeconv = localeconv();
|
||||
self::$_decimalSeparator = ($localeconv['decimal_point'] != '')
|
||||
? $localeconv['decimal_point'] : $localeconv['mon_decimal_point'];
|
||||
|
||||
if (self::$_decimalSeparator == '') {
|
||||
// Default to .
|
||||
self::$_decimalSeparator = '.';
|
||||
}
|
||||
}
|
||||
return self::$_decimalSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the decimal separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString()
|
||||
* to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF
|
||||
*
|
||||
* @param string $pValue Character for decimal separator
|
||||
*/
|
||||
public static function setDecimalSeparator($pValue = '.')
|
||||
{
|
||||
self::$_decimalSeparator = $pValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thousands separator. If it has not yet been set explicitly, try to obtain number
|
||||
* formatting information from locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getThousandsSeparator()
|
||||
{
|
||||
if (!isset(self::$_thousandsSeparator)) {
|
||||
$localeconv = localeconv();
|
||||
self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '')
|
||||
? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep'];
|
||||
|
||||
if (self::$_thousandsSeparator == '') {
|
||||
// Default to .
|
||||
self::$_thousandsSeparator = ',';
|
||||
}
|
||||
}
|
||||
return self::$_thousandsSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thousands separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString()
|
||||
* to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF
|
||||
*
|
||||
* @param string $pValue Character for thousands separator
|
||||
*/
|
||||
public static function setThousandsSeparator($pValue = ',')
|
||||
{
|
||||
self::$_thousandsSeparator = $pValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currency code. If it has not yet been set explicitly, try to obtain the
|
||||
* symbol information from locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurrencyCode()
|
||||
{
|
||||
if (!isset(self::$_currencyCode)) {
|
||||
$localeconv = localeconv();
|
||||
self::$_currencyCode = ($localeconv['currency_symbol'] != '')
|
||||
? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol'];
|
||||
|
||||
if (self::$_currencyCode == '') {
|
||||
// Default to $
|
||||
self::$_currencyCode = '$';
|
||||
}
|
||||
}
|
||||
return self::$_currencyCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the currency code. Only used by PHPExcel_Style_NumberFormat::toFormattedString()
|
||||
* to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF
|
||||
*
|
||||
* @param string $pValue Character for currency code
|
||||
*/
|
||||
public static function setCurrencyCode($pValue = '$')
|
||||
{
|
||||
self::$_currencyCode = $pValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert SYLK encoded string to UTF-8
|
||||
*
|
||||
* @param string $pValue
|
||||
* @return string UTF-8 encoded string
|
||||
*/
|
||||
public static function SYLKtoUTF8($pValue = '')
|
||||
{
|
||||
// If there is no escape character in the string there is nothing to do
|
||||
if (strpos($pValue, '') === false) {
|
||||
return $pValue;
|
||||
}
|
||||
|
||||
foreach (self::$_SYLKCharacters as $k => $v) {
|
||||
$pValue = str_replace($k, $v, $pValue);
|
||||
}
|
||||
|
||||
return $pValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve any leading numeric part of a string, or return the full string if no leading numeric
|
||||
* (handles basic integer or float, but not exponent or non decimal)
|
||||
*
|
||||
* @param string $value
|
||||
* @return mixed string or only the leading numeric part of the string
|
||||
*/
|
||||
public static function testStringAsNumeric($value)
|
||||
{
|
||||
if (is_numeric($value))
|
||||
return $value;
|
||||
$v = floatval($value);
|
||||
return (is_numeric(substr($value,0,strlen($v)))) ? $v : $value;
|
||||
}
|
||||
}
|
140
extend/phpexcel/PHPExcel/Shared/TimeZone.php
Executable file
140
extend/phpexcel/PHPExcel/Shared/TimeZone.php
Executable file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_TimeZone
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_TimeZone
|
||||
{
|
||||
/*
|
||||
* Default Timezone used for date/time conversions
|
||||
*
|
||||
* @private
|
||||
* @var string
|
||||
*/
|
||||
protected static $_timezone = 'UTC';
|
||||
|
||||
/**
|
||||
* Validate a Timezone name
|
||||
*
|
||||
* @param string $timezone Time zone (e.g. 'Europe/London')
|
||||
* @return boolean Success or failure
|
||||
*/
|
||||
public static function _validateTimeZone($timezone) {
|
||||
if (in_array($timezone, DateTimeZone::listIdentifiers())) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Default Timezone used for date/time conversions
|
||||
*
|
||||
* @param string $timezone Time zone (e.g. 'Europe/London')
|
||||
* @return boolean Success or failure
|
||||
*/
|
||||
public static function setTimeZone($timezone) {
|
||||
if (self::_validateTimezone($timezone)) {
|
||||
self::$_timezone = $timezone;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
} // function setTimezone()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Default Timezone used for date/time conversions
|
||||
*
|
||||
* @return string Timezone (e.g. 'Europe/London')
|
||||
*/
|
||||
public static function getTimeZone() {
|
||||
return self::$_timezone;
|
||||
} // function getTimezone()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Timezone transition for the specified timezone and timestamp
|
||||
*
|
||||
* @param DateTimeZone $objTimezone The timezone for finding the transitions
|
||||
* @param integer $timestamp PHP date/time value for finding the current transition
|
||||
* @return array The current transition details
|
||||
*/
|
||||
private static function _getTimezoneTransitions($objTimezone, $timestamp) {
|
||||
$allTransitions = $objTimezone->getTransitions();
|
||||
$transitions = array();
|
||||
foreach($allTransitions as $key => $transition) {
|
||||
if ($transition['ts'] > $timestamp) {
|
||||
$transitions[] = ($key > 0) ? $allTransitions[$key - 1] : $transition;
|
||||
break;
|
||||
}
|
||||
if (empty($transitions)) {
|
||||
$transitions[] = end($allTransitions);
|
||||
}
|
||||
}
|
||||
|
||||
return $transitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Timezone offset used for date/time conversions to/from UST
|
||||
* This requires both the timezone and the calculated date/time to allow for local DST
|
||||
*
|
||||
* @param string $timezone The timezone for finding the adjustment to UST
|
||||
* @param integer $timestamp PHP date/time value
|
||||
* @return integer Number of seconds for timezone adjustment
|
||||
* @throws PHPExcel_Exception
|
||||
*/
|
||||
public static function getTimeZoneAdjustment($timezone, $timestamp) {
|
||||
if ($timezone !== NULL) {
|
||||
if (!self::_validateTimezone($timezone)) {
|
||||
throw new PHPExcel_Exception("Invalid timezone " . $timezone);
|
||||
}
|
||||
} else {
|
||||
$timezone = self::$_timezone;
|
||||
}
|
||||
|
||||
if ($timezone == 'UST') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$objTimezone = new DateTimeZone($timezone);
|
||||
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
|
||||
$transitions = $objTimezone->getTransitions($timestamp,$timestamp);
|
||||
} else {
|
||||
$transitions = self::_getTimezoneTransitions($objTimezone, $timestamp);
|
||||
}
|
||||
|
||||
return (count($transitions) > 0) ? $transitions[0]['offset'] : 0;
|
||||
}
|
||||
|
||||
}
|
127
extend/phpexcel/PHPExcel/Shared/XMLWriter.php
Executable file
127
extend/phpexcel/PHPExcel/Shared/XMLWriter.php
Executable file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
if (!defined('DATE_W3C')) {
|
||||
define('DATE_W3C', 'Y-m-d\TH:i:sP');
|
||||
}
|
||||
|
||||
if (!defined('DEBUGMODE_ENABLED')) {
|
||||
define('DEBUGMODE_ENABLED', false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_XMLWriter
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_XMLWriter extends XMLWriter {
|
||||
/** Temporary storage method */
|
||||
const STORAGE_MEMORY = 1;
|
||||
const STORAGE_DISK = 2;
|
||||
|
||||
/**
|
||||
* Temporary filename
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_tempFileName = '';
|
||||
|
||||
/**
|
||||
* Create a new PHPExcel_Shared_XMLWriter instance
|
||||
*
|
||||
* @param int $pTemporaryStorage Temporary storage location
|
||||
* @param string $pTemporaryStorageFolder Temporary storage folder
|
||||
*/
|
||||
public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = NULL) {
|
||||
// Open temporary storage
|
||||
if ($pTemporaryStorage == self::STORAGE_MEMORY) {
|
||||
$this->openMemory();
|
||||
} else {
|
||||
// Create temporary filename
|
||||
if ($pTemporaryStorageFolder === NULL)
|
||||
$pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir();
|
||||
$this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml');
|
||||
|
||||
// Open storage
|
||||
if ($this->openUri($this->_tempFileName) === false) {
|
||||
// Fallback to memory...
|
||||
$this->openMemory();
|
||||
}
|
||||
}
|
||||
|
||||
// Set default values
|
||||
if (DEBUGMODE_ENABLED) {
|
||||
$this->setIndent(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct() {
|
||||
// Unlink temporary files
|
||||
if ($this->_tempFileName != '') {
|
||||
@unlink($this->_tempFileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get written data
|
||||
*
|
||||
* @return $data
|
||||
*/
|
||||
public function getData() {
|
||||
if ($this->_tempFileName == '') {
|
||||
return $this->outputMemory(true);
|
||||
} else {
|
||||
$this->flush();
|
||||
return file_get_contents($this->_tempFileName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback method for writeRaw, introduced in PHP 5.2
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public function writeRawData($text)
|
||||
{
|
||||
if (is_array($text)) {
|
||||
$text = implode("\n",$text);
|
||||
}
|
||||
|
||||
if (method_exists($this, 'writeRaw')) {
|
||||
return $this->writeRaw(htmlspecialchars($text));
|
||||
}
|
||||
|
||||
return $this->text($text);
|
||||
}
|
||||
}
|
175
extend/phpexcel/PHPExcel/Shared/ZipArchive.php
Executable file
175
extend/phpexcel/PHPExcel/Shared/ZipArchive.php
Executable file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_ZipArchive
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
if (!defined('PCLZIP_TEMPORARY_DIR')) {
|
||||
define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir());
|
||||
}
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php';
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_ZipArchive
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_ZipArchive
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_ZipArchive
|
||||
{
|
||||
|
||||
/** constants */
|
||||
const OVERWRITE = 'OVERWRITE';
|
||||
const CREATE = 'CREATE';
|
||||
|
||||
|
||||
/**
|
||||
* Temporary storage directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_tempDir;
|
||||
|
||||
/**
|
||||
* Zip Archive Stream Handle
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_zip;
|
||||
|
||||
|
||||
/**
|
||||
* Open a new zip archive
|
||||
*
|
||||
* @param string $fileName Filename for the zip archive
|
||||
* @return boolean
|
||||
*/
|
||||
public function open($fileName)
|
||||
{
|
||||
$this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir();
|
||||
|
||||
$this->_zip = new PclZip($fileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close this zip archive
|
||||
*
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new file to the zip archive from a string of raw data.
|
||||
*
|
||||
* @param string $localname Directory/Name of the file to add to the zip archive
|
||||
* @param string $contents String of data to add to the zip archive
|
||||
*/
|
||||
public function addFromString($localname, $contents)
|
||||
{
|
||||
$filenameParts = pathinfo($localname);
|
||||
|
||||
$handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb");
|
||||
fwrite($handle, $contents);
|
||||
fclose($handle);
|
||||
|
||||
$res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"],
|
||||
PCLZIP_OPT_REMOVE_PATH, $this->_tempDir,
|
||||
PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"]
|
||||
);
|
||||
if ($res == 0) {
|
||||
throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true));
|
||||
}
|
||||
|
||||
unlink($this->_tempDir.'/'.$filenameParts["basename"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find if given fileName exist in archive (Emulate ZipArchive locateName())
|
||||
*
|
||||
* @param string $fileName Filename for the file in zip archive
|
||||
* @return boolean
|
||||
*/
|
||||
public function locateName($fileName)
|
||||
{
|
||||
$list = $this->_zip->listContent();
|
||||
$listCount = count($list);
|
||||
$list_index = -1;
|
||||
for ($i = 0; $i < $listCount; ++$i) {
|
||||
if (strtolower($list[$i]["filename"]) == strtolower($fileName) ||
|
||||
strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) {
|
||||
$list_index = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ($list_index > -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract file from archive by given fileName (Emulate ZipArchive getFromName())
|
||||
*
|
||||
* @param string $fileName Filename for the file in zip archive
|
||||
* @return string $contents File string contents
|
||||
*/
|
||||
public function getFromName($fileName)
|
||||
{
|
||||
$list = $this->_zip->listContent();
|
||||
$listCount = count($list);
|
||||
$list_index = -1;
|
||||
for ($i = 0; $i < $listCount; ++$i) {
|
||||
if (strtolower($list[$i]["filename"]) == strtolower($fileName) ||
|
||||
strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) {
|
||||
$list_index = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$extracted = "";
|
||||
if ($list_index != -1) {
|
||||
$extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING);
|
||||
} else {
|
||||
$filename = substr($fileName, 1);
|
||||
$list_index = -1;
|
||||
for ($i = 0; $i < $listCount; ++$i) {
|
||||
if (strtolower($list[$i]["filename"]) == strtolower($fileName) ||
|
||||
strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) {
|
||||
$list_index = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING);
|
||||
}
|
||||
if ((is_array($extracted)) && ($extracted != 0)) {
|
||||
$contents = $extracted[0]["content"];
|
||||
}
|
||||
|
||||
return $contents;
|
||||
}
|
||||
}
|
201
extend/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php
Executable file
201
extend/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php
Executable file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Shared_ZipStreamWrapper
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Shared_ZipStreamWrapper {
|
||||
/**
|
||||
* Internal ZipAcrhive
|
||||
*
|
||||
* @var ZipAcrhive
|
||||
*/
|
||||
private $_archive;
|
||||
|
||||
/**
|
||||
* Filename in ZipAcrhive
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_fileNameInArchive = '';
|
||||
|
||||
/**
|
||||
* Position in file
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_position = 0;
|
||||
|
||||
/**
|
||||
* Data
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $_data = '';
|
||||
|
||||
/**
|
||||
* Register wrapper
|
||||
*/
|
||||
public static function register() {
|
||||
@stream_wrapper_unregister("zip");
|
||||
@stream_wrapper_register("zip", __CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fopen().
|
||||
*
|
||||
* @param string $path resource name including scheme, e.g.
|
||||
* @param string $mode only "r" is supported
|
||||
* @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH
|
||||
* @param string &$openedPath absolute path of the opened stream (out parameter)
|
||||
* @return bool true on success
|
||||
*/
|
||||
public function stream_open($path, $mode, $options, &$opened_path) {
|
||||
// Check for mode
|
||||
if ($mode{0} != 'r') {
|
||||
throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.');
|
||||
}
|
||||
|
||||
$pos = strrpos($path, '#');
|
||||
$url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://')
|
||||
$url['fragment'] = substr($path, $pos + 1);
|
||||
|
||||
// Open archive
|
||||
$this->_archive = new ZipArchive();
|
||||
$this->_archive->open($url['host']);
|
||||
|
||||
$this->_fileNameInArchive = $url['fragment'];
|
||||
$this->_position = 0;
|
||||
$this->_data = $this->_archive->getFromName( $this->_fileNameInArchive );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fstat().
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function statName() {
|
||||
return $this->_fileNameInArchive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fstat().
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function url_stat() {
|
||||
return $this->statName( $this->_fileNameInArchive );
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fstat().
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function stream_stat() {
|
||||
return $this->_archive->statName( $this->_fileNameInArchive );
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fread(), fgets() etc.
|
||||
*
|
||||
* @param int $count maximum number of bytes to read
|
||||
* @return string
|
||||
*/
|
||||
function stream_read($count) {
|
||||
$ret = substr($this->_data, $this->_position, $count);
|
||||
$this->_position += strlen($ret);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the file pointer, i.e. its offset into the file
|
||||
* stream. Implements support for ftell().
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function stream_tell() {
|
||||
return $this->_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* EOF stream
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_eof() {
|
||||
return $this->_position >= strlen($this->_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek stream
|
||||
*
|
||||
* @param int $offset byte offset
|
||||
* @param int $whence SEEK_SET, SEEK_CUR or SEEK_END
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_seek($offset, $whence) {
|
||||
switch ($whence) {
|
||||
case SEEK_SET:
|
||||
if ($offset < strlen($this->_data) && $offset >= 0) {
|
||||
$this->_position = $offset;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
if ($offset >= 0) {
|
||||
$this->_position += $offset;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if (strlen($this->_data) + $offset >= 0) {
|
||||
$this->_position = strlen($this->_data) + $offset;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
432
extend/phpexcel/PHPExcel/Shared/trend/bestFitClass.php
Executable file
432
extend/phpexcel/PHPExcel/Shared/trend/bestFitClass.php
Executable file
@ -0,0 +1,432 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Best_Fit
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Best_Fit
|
||||
{
|
||||
/**
|
||||
* Indicator flag for a calculation error
|
||||
*
|
||||
* @var boolean
|
||||
**/
|
||||
protected $_error = False;
|
||||
|
||||
/**
|
||||
* Algorithm type to use for best-fit
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $_bestFitType = 'undetermined';
|
||||
|
||||
/**
|
||||
* Number of entries in the sets of x- and y-value arrays
|
||||
*
|
||||
* @var int
|
||||
**/
|
||||
protected $_valueCount = 0;
|
||||
|
||||
/**
|
||||
* X-value dataseries of values
|
||||
*
|
||||
* @var float[]
|
||||
**/
|
||||
protected $_xValues = array();
|
||||
|
||||
/**
|
||||
* Y-value dataseries of values
|
||||
*
|
||||
* @var float[]
|
||||
**/
|
||||
protected $_yValues = array();
|
||||
|
||||
/**
|
||||
* Flag indicating whether values should be adjusted to Y=0
|
||||
*
|
||||
* @var boolean
|
||||
**/
|
||||
protected $_adjustToZero = False;
|
||||
|
||||
/**
|
||||
* Y-value series of best-fit values
|
||||
*
|
||||
* @var float[]
|
||||
**/
|
||||
protected $_yBestFitValues = array();
|
||||
|
||||
protected $_goodnessOfFit = 1;
|
||||
|
||||
protected $_stdevOfResiduals = 0;
|
||||
|
||||
protected $_covariance = 0;
|
||||
|
||||
protected $_correlation = 0;
|
||||
|
||||
protected $_SSRegression = 0;
|
||||
|
||||
protected $_SSResiduals = 0;
|
||||
|
||||
protected $_DFResiduals = 0;
|
||||
|
||||
protected $_F = 0;
|
||||
|
||||
protected $_slope = 0;
|
||||
|
||||
protected $_slopeSE = 0;
|
||||
|
||||
protected $_intersect = 0;
|
||||
|
||||
protected $_intersectSE = 0;
|
||||
|
||||
protected $_Xoffset = 0;
|
||||
|
||||
protected $_Yoffset = 0;
|
||||
|
||||
|
||||
public function getError() {
|
||||
return $this->_error;
|
||||
} // function getBestFitType()
|
||||
|
||||
|
||||
public function getBestFitType() {
|
||||
return $this->_bestFitType;
|
||||
} // function getBestFitType()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Y-Value for a specified value of X
|
||||
*
|
||||
* @param float $xValue X-Value
|
||||
* @return float Y-Value
|
||||
*/
|
||||
public function getValueOfYForX($xValue) {
|
||||
return False;
|
||||
} // function getValueOfYForX()
|
||||
|
||||
|
||||
/**
|
||||
* Return the X-Value for a specified value of Y
|
||||
*
|
||||
* @param float $yValue Y-Value
|
||||
* @return float X-Value
|
||||
*/
|
||||
public function getValueOfXForY($yValue) {
|
||||
return False;
|
||||
} // function getValueOfXForY()
|
||||
|
||||
|
||||
/**
|
||||
* Return the original set of X-Values
|
||||
*
|
||||
* @return float[] X-Values
|
||||
*/
|
||||
public function getXValues() {
|
||||
return $this->_xValues;
|
||||
} // function getValueOfXForY()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Equation of the best-fit line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
*/
|
||||
public function getEquation($dp=0) {
|
||||
return False;
|
||||
} // function getEquation()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Slope of the line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
*/
|
||||
public function getSlope($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_slope,$dp);
|
||||
}
|
||||
return $this->_slope;
|
||||
} // function getSlope()
|
||||
|
||||
|
||||
/**
|
||||
* Return the standard error of the Slope
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
*/
|
||||
public function getSlopeSE($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_slopeSE,$dp);
|
||||
}
|
||||
return $this->_slopeSE;
|
||||
} // function getSlopeSE()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Value of X where it intersects Y = 0
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
*/
|
||||
public function getIntersect($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_intersect,$dp);
|
||||
}
|
||||
return $this->_intersect;
|
||||
} // function getIntersect()
|
||||
|
||||
|
||||
/**
|
||||
* Return the standard error of the Intersect
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
*/
|
||||
public function getIntersectSE($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_intersectSE,$dp);
|
||||
}
|
||||
return $this->_intersectSE;
|
||||
} // function getIntersectSE()
|
||||
|
||||
|
||||
/**
|
||||
* Return the goodness of fit for this regression
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
* @return float
|
||||
*/
|
||||
public function getGoodnessOfFit($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_goodnessOfFit,$dp);
|
||||
}
|
||||
return $this->_goodnessOfFit;
|
||||
} // function getGoodnessOfFit()
|
||||
|
||||
|
||||
public function getGoodnessOfFitPercent($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_goodnessOfFit * 100,$dp);
|
||||
}
|
||||
return $this->_goodnessOfFit * 100;
|
||||
} // function getGoodnessOfFitPercent()
|
||||
|
||||
|
||||
/**
|
||||
* Return the standard deviation of the residuals for this regression
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to return
|
||||
* @return float
|
||||
*/
|
||||
public function getStdevOfResiduals($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_stdevOfResiduals,$dp);
|
||||
}
|
||||
return $this->_stdevOfResiduals;
|
||||
} // function getStdevOfResiduals()
|
||||
|
||||
|
||||
public function getSSRegression($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_SSRegression,$dp);
|
||||
}
|
||||
return $this->_SSRegression;
|
||||
} // function getSSRegression()
|
||||
|
||||
|
||||
public function getSSResiduals($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_SSResiduals,$dp);
|
||||
}
|
||||
return $this->_SSResiduals;
|
||||
} // function getSSResiduals()
|
||||
|
||||
|
||||
public function getDFResiduals($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_DFResiduals,$dp);
|
||||
}
|
||||
return $this->_DFResiduals;
|
||||
} // function getDFResiduals()
|
||||
|
||||
|
||||
public function getF($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_F,$dp);
|
||||
}
|
||||
return $this->_F;
|
||||
} // function getF()
|
||||
|
||||
|
||||
public function getCovariance($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_covariance,$dp);
|
||||
}
|
||||
return $this->_covariance;
|
||||
} // function getCovariance()
|
||||
|
||||
|
||||
public function getCorrelation($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round($this->_correlation,$dp);
|
||||
}
|
||||
return $this->_correlation;
|
||||
} // function getCorrelation()
|
||||
|
||||
|
||||
public function getYBestFitValues() {
|
||||
return $this->_yBestFitValues;
|
||||
} // function getYBestFitValues()
|
||||
|
||||
|
||||
protected function _calculateGoodnessOfFit($sumX,$sumY,$sumX2,$sumY2,$sumXY,$meanX,$meanY, $const) {
|
||||
$SSres = $SScov = $SScor = $SStot = $SSsex = 0.0;
|
||||
foreach($this->_xValues as $xKey => $xValue) {
|
||||
$bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
|
||||
|
||||
$SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY);
|
||||
if ($const) {
|
||||
$SStot += ($this->_yValues[$xKey] - $meanY) * ($this->_yValues[$xKey] - $meanY);
|
||||
} else {
|
||||
$SStot += $this->_yValues[$xKey] * $this->_yValues[$xKey];
|
||||
}
|
||||
$SScov += ($this->_xValues[$xKey] - $meanX) * ($this->_yValues[$xKey] - $meanY);
|
||||
if ($const) {
|
||||
$SSsex += ($this->_xValues[$xKey] - $meanX) * ($this->_xValues[$xKey] - $meanX);
|
||||
} else {
|
||||
$SSsex += $this->_xValues[$xKey] * $this->_xValues[$xKey];
|
||||
}
|
||||
}
|
||||
|
||||
$this->_SSResiduals = $SSres;
|
||||
$this->_DFResiduals = $this->_valueCount - 1 - $const;
|
||||
|
||||
if ($this->_DFResiduals == 0.0) {
|
||||
$this->_stdevOfResiduals = 0.0;
|
||||
} else {
|
||||
$this->_stdevOfResiduals = sqrt($SSres / $this->_DFResiduals);
|
||||
}
|
||||
if (($SStot == 0.0) || ($SSres == $SStot)) {
|
||||
$this->_goodnessOfFit = 1;
|
||||
} else {
|
||||
$this->_goodnessOfFit = 1 - ($SSres / $SStot);
|
||||
}
|
||||
|
||||
$this->_SSRegression = $this->_goodnessOfFit * $SStot;
|
||||
$this->_covariance = $SScov / $this->_valueCount;
|
||||
$this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX,2)) * ($this->_valueCount * $sumY2 - pow($sumY,2)));
|
||||
$this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex);
|
||||
$this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2));
|
||||
if ($this->_SSResiduals != 0.0) {
|
||||
if ($this->_DFResiduals == 0.0) {
|
||||
$this->_F = 0.0;
|
||||
} else {
|
||||
$this->_F = $this->_SSRegression / ($this->_SSResiduals / $this->_DFResiduals);
|
||||
}
|
||||
} else {
|
||||
if ($this->_DFResiduals == 0.0) {
|
||||
$this->_F = 0.0;
|
||||
} else {
|
||||
$this->_F = $this->_SSRegression / $this->_DFResiduals;
|
||||
}
|
||||
}
|
||||
} // function _calculateGoodnessOfFit()
|
||||
|
||||
|
||||
protected function _leastSquareFit($yValues, $xValues, $const) {
|
||||
// calculate sums
|
||||
$x_sum = array_sum($xValues);
|
||||
$y_sum = array_sum($yValues);
|
||||
$meanX = $x_sum / $this->_valueCount;
|
||||
$meanY = $y_sum / $this->_valueCount;
|
||||
$mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0;
|
||||
for($i = 0; $i < $this->_valueCount; ++$i) {
|
||||
$xy_sum += $xValues[$i] * $yValues[$i];
|
||||
$xx_sum += $xValues[$i] * $xValues[$i];
|
||||
$yy_sum += $yValues[$i] * $yValues[$i];
|
||||
|
||||
if ($const) {
|
||||
$mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY);
|
||||
$mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX);
|
||||
} else {
|
||||
$mBase += $xValues[$i] * $yValues[$i];
|
||||
$mDivisor += $xValues[$i] * $xValues[$i];
|
||||
}
|
||||
}
|
||||
|
||||
// calculate slope
|
||||
// $this->_slope = (($this->_valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->_valueCount * $xx_sum) - ($x_sum * $x_sum));
|
||||
$this->_slope = $mBase / $mDivisor;
|
||||
|
||||
// calculate intersect
|
||||
// $this->_intersect = ($y_sum - ($this->_slope * $x_sum)) / $this->_valueCount;
|
||||
if ($const) {
|
||||
$this->_intersect = $meanY - ($this->_slope * $meanX);
|
||||
} else {
|
||||
$this->_intersect = 0;
|
||||
}
|
||||
|
||||
$this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum,$meanX,$meanY,$const);
|
||||
} // function _leastSquareFit()
|
||||
|
||||
|
||||
/**
|
||||
* Define the regression
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
function __construct($yValues, $xValues=array(), $const=True) {
|
||||
// Calculate number of points
|
||||
$nY = count($yValues);
|
||||
$nX = count($xValues);
|
||||
|
||||
// Define X Values if necessary
|
||||
if ($nX == 0) {
|
||||
$xValues = range(1,$nY);
|
||||
$nX = $nY;
|
||||
} elseif ($nY != $nX) {
|
||||
// Ensure both arrays of points are the same size
|
||||
$this->_error = True;
|
||||
return False;
|
||||
}
|
||||
|
||||
$this->_valueCount = $nY;
|
||||
$this->_xValues = $xValues;
|
||||
$this->_yValues = $yValues;
|
||||
} // function __construct()
|
||||
|
||||
} // class bestFit
|
148
extend/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php
Executable file
148
extend/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php
Executable file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php');
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Exponential_Best_Fit
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit
|
||||
{
|
||||
/**
|
||||
* Algorithm type to use for best-fit
|
||||
* (Name of this trend class)
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $_bestFitType = 'exponential';
|
||||
|
||||
|
||||
/**
|
||||
* Return the Y-Value for a specified value of X
|
||||
*
|
||||
* @param float $xValue X-Value
|
||||
* @return float Y-Value
|
||||
**/
|
||||
public function getValueOfYForX($xValue) {
|
||||
return $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset));
|
||||
} // function getValueOfYForX()
|
||||
|
||||
|
||||
/**
|
||||
* Return the X-Value for a specified value of Y
|
||||
*
|
||||
* @param float $yValue Y-Value
|
||||
* @return float X-Value
|
||||
**/
|
||||
public function getValueOfXForY($yValue) {
|
||||
return log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope());
|
||||
} // function getValueOfXForY()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Equation of the best-fit line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getEquation($dp=0) {
|
||||
$slope = $this->getSlope($dp);
|
||||
$intersect = $this->getIntersect($dp);
|
||||
|
||||
return 'Y = '.$intersect.' * '.$slope.'^X';
|
||||
} // function getEquation()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Slope of the line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getSlope($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round(exp($this->_slope),$dp);
|
||||
}
|
||||
return exp($this->_slope);
|
||||
} // function getSlope()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Value of X where it intersects Y = 0
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getIntersect($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round(exp($this->_intersect),$dp);
|
||||
}
|
||||
return exp($this->_intersect);
|
||||
} // function getIntersect()
|
||||
|
||||
|
||||
/**
|
||||
* Execute the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
private function _exponential_regression($yValues, $xValues, $const) {
|
||||
foreach($yValues as &$value) {
|
||||
if ($value < 0.0) {
|
||||
$value = 0 - log(abs($value));
|
||||
} elseif ($value > 0.0) {
|
||||
$value = log($value);
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
|
||||
$this->_leastSquareFit($yValues, $xValues, $const);
|
||||
} // function _exponential_regression()
|
||||
|
||||
|
||||
/**
|
||||
* Define the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
function __construct($yValues, $xValues=array(), $const=True) {
|
||||
if (parent::__construct($yValues, $xValues) !== False) {
|
||||
$this->_exponential_regression($yValues, $xValues, $const);
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
} // class exponentialBestFit
|
111
extend/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php
Executable file
111
extend/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php
Executable file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php');
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Linear_Best_Fit
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit
|
||||
{
|
||||
/**
|
||||
* Algorithm type to use for best-fit
|
||||
* (Name of this trend class)
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $_bestFitType = 'linear';
|
||||
|
||||
|
||||
/**
|
||||
* Return the Y-Value for a specified value of X
|
||||
*
|
||||
* @param float $xValue X-Value
|
||||
* @return float Y-Value
|
||||
**/
|
||||
public function getValueOfYForX($xValue) {
|
||||
return $this->getIntersect() + $this->getSlope() * $xValue;
|
||||
} // function getValueOfYForX()
|
||||
|
||||
|
||||
/**
|
||||
* Return the X-Value for a specified value of Y
|
||||
*
|
||||
* @param float $yValue Y-Value
|
||||
* @return float X-Value
|
||||
**/
|
||||
public function getValueOfXForY($yValue) {
|
||||
return ($yValue - $this->getIntersect()) / $this->getSlope();
|
||||
} // function getValueOfXForY()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Equation of the best-fit line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getEquation($dp=0) {
|
||||
$slope = $this->getSlope($dp);
|
||||
$intersect = $this->getIntersect($dp);
|
||||
|
||||
return 'Y = '.$intersect.' + '.$slope.' * X';
|
||||
} // function getEquation()
|
||||
|
||||
|
||||
/**
|
||||
* Execute the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
private function _linear_regression($yValues, $xValues, $const) {
|
||||
$this->_leastSquareFit($yValues, $xValues,$const);
|
||||
} // function _linear_regression()
|
||||
|
||||
|
||||
/**
|
||||
* Define the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
function __construct($yValues, $xValues=array(), $const=True) {
|
||||
if (parent::__construct($yValues, $xValues) !== False) {
|
||||
$this->_linear_regression($yValues, $xValues, $const);
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
} // class linearBestFit
|
120
extend/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php
Executable file
120
extend/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php
Executable file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php');
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Logarithmic_Best_Fit
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit
|
||||
{
|
||||
/**
|
||||
* Algorithm type to use for best-fit
|
||||
* (Name of this trend class)
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $_bestFitType = 'logarithmic';
|
||||
|
||||
|
||||
/**
|
||||
* Return the Y-Value for a specified value of X
|
||||
*
|
||||
* @param float $xValue X-Value
|
||||
* @return float Y-Value
|
||||
**/
|
||||
public function getValueOfYForX($xValue) {
|
||||
return $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset);
|
||||
} // function getValueOfYForX()
|
||||
|
||||
|
||||
/**
|
||||
* Return the X-Value for a specified value of Y
|
||||
*
|
||||
* @param float $yValue Y-Value
|
||||
* @return float X-Value
|
||||
**/
|
||||
public function getValueOfXForY($yValue) {
|
||||
return exp(($yValue - $this->getIntersect()) / $this->getSlope());
|
||||
} // function getValueOfXForY()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Equation of the best-fit line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getEquation($dp=0) {
|
||||
$slope = $this->getSlope($dp);
|
||||
$intersect = $this->getIntersect($dp);
|
||||
|
||||
return 'Y = '.$intersect.' + '.$slope.' * log(X)';
|
||||
} // function getEquation()
|
||||
|
||||
|
||||
/**
|
||||
* Execute the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
private function _logarithmic_regression($yValues, $xValues, $const) {
|
||||
foreach($xValues as &$value) {
|
||||
if ($value < 0.0) {
|
||||
$value = 0 - log(abs($value));
|
||||
} elseif ($value > 0.0) {
|
||||
$value = log($value);
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
|
||||
$this->_leastSquareFit($yValues, $xValues, $const);
|
||||
} // function _logarithmic_regression()
|
||||
|
||||
|
||||
/**
|
||||
* Define the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
function __construct($yValues, $xValues=array(), $const=True) {
|
||||
if (parent::__construct($yValues, $xValues) !== False) {
|
||||
$this->_logarithmic_regression($yValues, $xValues, $const);
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
} // class logarithmicBestFit
|
224
extend/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php
Executable file
224
extend/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php
Executable file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php';
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php';
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Polynomial_Best_Fit
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit
|
||||
{
|
||||
/**
|
||||
* Algorithm type to use for best-fit
|
||||
* (Name of this trend class)
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $_bestFitType = 'polynomial';
|
||||
|
||||
/**
|
||||
* Polynomial order
|
||||
*
|
||||
* @protected
|
||||
* @var int
|
||||
**/
|
||||
protected $_order = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Return the order of this polynomial
|
||||
*
|
||||
* @return int
|
||||
**/
|
||||
public function getOrder() {
|
||||
return $this->_order;
|
||||
} // function getOrder()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Y-Value for a specified value of X
|
||||
*
|
||||
* @param float $xValue X-Value
|
||||
* @return float Y-Value
|
||||
**/
|
||||
public function getValueOfYForX($xValue) {
|
||||
$retVal = $this->getIntersect();
|
||||
$slope = $this->getSlope();
|
||||
foreach($slope as $key => $value) {
|
||||
if ($value != 0.0) {
|
||||
$retVal += $value * pow($xValue, $key + 1);
|
||||
}
|
||||
}
|
||||
return $retVal;
|
||||
} // function getValueOfYForX()
|
||||
|
||||
|
||||
/**
|
||||
* Return the X-Value for a specified value of Y
|
||||
*
|
||||
* @param float $yValue Y-Value
|
||||
* @return float X-Value
|
||||
**/
|
||||
public function getValueOfXForY($yValue) {
|
||||
return ($yValue - $this->getIntersect()) / $this->getSlope();
|
||||
} // function getValueOfXForY()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Equation of the best-fit line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getEquation($dp=0) {
|
||||
$slope = $this->getSlope($dp);
|
||||
$intersect = $this->getIntersect($dp);
|
||||
|
||||
$equation = 'Y = '.$intersect;
|
||||
foreach($slope as $key => $value) {
|
||||
if ($value != 0.0) {
|
||||
$equation .= ' + '.$value.' * X';
|
||||
if ($key > 0) {
|
||||
$equation .= '^'.($key + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $equation;
|
||||
} // function getEquation()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Slope of the line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getSlope($dp=0) {
|
||||
if ($dp != 0) {
|
||||
$coefficients = array();
|
||||
foreach($this->_slope as $coefficient) {
|
||||
$coefficients[] = round($coefficient,$dp);
|
||||
}
|
||||
return $coefficients;
|
||||
}
|
||||
return $this->_slope;
|
||||
} // function getSlope()
|
||||
|
||||
|
||||
public function getCoefficients($dp=0) {
|
||||
return array_merge(array($this->getIntersect($dp)),$this->getSlope($dp));
|
||||
} // function getCoefficients()
|
||||
|
||||
|
||||
/**
|
||||
* Execute the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param int $order Order of Polynomial for this regression
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
private function _polynomial_regression($order, $yValues, $xValues, $const) {
|
||||
// calculate sums
|
||||
$x_sum = array_sum($xValues);
|
||||
$y_sum = array_sum($yValues);
|
||||
$xx_sum = $xy_sum = 0;
|
||||
for($i = 0; $i < $this->_valueCount; ++$i) {
|
||||
$xy_sum += $xValues[$i] * $yValues[$i];
|
||||
$xx_sum += $xValues[$i] * $xValues[$i];
|
||||
$yy_sum += $yValues[$i] * $yValues[$i];
|
||||
}
|
||||
/*
|
||||
* This routine uses logic from the PHP port of polyfit version 0.1
|
||||
* written by Michael Bommarito and Paul Meagher
|
||||
*
|
||||
* The function fits a polynomial function of order $order through
|
||||
* a series of x-y data points using least squares.
|
||||
*
|
||||
*/
|
||||
for ($i = 0; $i < $this->_valueCount; ++$i) {
|
||||
for ($j = 0; $j <= $order; ++$j) {
|
||||
$A[$i][$j] = pow($xValues[$i], $j);
|
||||
}
|
||||
}
|
||||
for ($i=0; $i < $this->_valueCount; ++$i) {
|
||||
$B[$i] = array($yValues[$i]);
|
||||
}
|
||||
$matrixA = new Matrix($A);
|
||||
$matrixB = new Matrix($B);
|
||||
$C = $matrixA->solve($matrixB);
|
||||
|
||||
$coefficients = array();
|
||||
for($i = 0; $i < $C->m; ++$i) {
|
||||
$r = $C->get($i, 0);
|
||||
if (abs($r) <= pow(10, -9)) {
|
||||
$r = 0;
|
||||
}
|
||||
$coefficients[] = $r;
|
||||
}
|
||||
|
||||
$this->_intersect = array_shift($coefficients);
|
||||
$this->_slope = $coefficients;
|
||||
|
||||
$this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum);
|
||||
foreach($this->_xValues as $xKey => $xValue) {
|
||||
$this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
|
||||
}
|
||||
} // function _polynomial_regression()
|
||||
|
||||
|
||||
/**
|
||||
* Define the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param int $order Order of Polynomial for this regression
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
function __construct($order, $yValues, $xValues=array(), $const=True) {
|
||||
if (parent::__construct($yValues, $xValues) !== False) {
|
||||
if ($order < $this->_valueCount) {
|
||||
$this->_bestFitType .= '_'.$order;
|
||||
$this->_order = $order;
|
||||
$this->_polynomial_regression($order, $yValues, $xValues, $const);
|
||||
if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) {
|
||||
$this->_error = True;
|
||||
}
|
||||
} else {
|
||||
$this->_error = True;
|
||||
}
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
} // class polynomialBestFit
|
142
extend/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php
Executable file
142
extend/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php
Executable file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php';
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_Power_Best_Fit
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit
|
||||
{
|
||||
/**
|
||||
* Algorithm type to use for best-fit
|
||||
* (Name of this trend class)
|
||||
*
|
||||
* @var string
|
||||
**/
|
||||
protected $_bestFitType = 'power';
|
||||
|
||||
|
||||
/**
|
||||
* Return the Y-Value for a specified value of X
|
||||
*
|
||||
* @param float $xValue X-Value
|
||||
* @return float Y-Value
|
||||
**/
|
||||
public function getValueOfYForX($xValue) {
|
||||
return $this->getIntersect() * pow(($xValue - $this->_Xoffset),$this->getSlope());
|
||||
} // function getValueOfYForX()
|
||||
|
||||
|
||||
/**
|
||||
* Return the X-Value for a specified value of Y
|
||||
*
|
||||
* @param float $yValue Y-Value
|
||||
* @return float X-Value
|
||||
**/
|
||||
public function getValueOfXForY($yValue) {
|
||||
return pow((($yValue + $this->_Yoffset) / $this->getIntersect()),(1 / $this->getSlope()));
|
||||
} // function getValueOfXForY()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Equation of the best-fit line
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getEquation($dp=0) {
|
||||
$slope = $this->getSlope($dp);
|
||||
$intersect = $this->getIntersect($dp);
|
||||
|
||||
return 'Y = '.$intersect.' * X^'.$slope;
|
||||
} // function getEquation()
|
||||
|
||||
|
||||
/**
|
||||
* Return the Value of X where it intersects Y = 0
|
||||
*
|
||||
* @param int $dp Number of places of decimal precision to display
|
||||
* @return string
|
||||
**/
|
||||
public function getIntersect($dp=0) {
|
||||
if ($dp != 0) {
|
||||
return round(exp($this->_intersect),$dp);
|
||||
}
|
||||
return exp($this->_intersect);
|
||||
} // function getIntersect()
|
||||
|
||||
|
||||
/**
|
||||
* Execute the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
private function _power_regression($yValues, $xValues, $const) {
|
||||
foreach($xValues as &$value) {
|
||||
if ($value < 0.0) {
|
||||
$value = 0 - log(abs($value));
|
||||
} elseif ($value > 0.0) {
|
||||
$value = log($value);
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
foreach($yValues as &$value) {
|
||||
if ($value < 0.0) {
|
||||
$value = 0 - log(abs($value));
|
||||
} elseif ($value > 0.0) {
|
||||
$value = log($value);
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
|
||||
$this->_leastSquareFit($yValues, $xValues, $const);
|
||||
} // function _power_regression()
|
||||
|
||||
|
||||
/**
|
||||
* Define the regression and calculate the goodness of fit for a set of X and Y data values
|
||||
*
|
||||
* @param float[] $yValues The set of Y-values for this regression
|
||||
* @param float[] $xValues The set of X-values for this regression
|
||||
* @param boolean $const
|
||||
*/
|
||||
function __construct($yValues, $xValues=array(), $const=True) {
|
||||
if (parent::__construct($yValues, $xValues) !== False) {
|
||||
$this->_power_regression($yValues, $xValues, $const);
|
||||
}
|
||||
} // function __construct()
|
||||
|
||||
} // class powerBestFit
|
156
extend/phpexcel/PHPExcel/Shared/trend/trendClass.php
Executable file
156
extend/phpexcel/PHPExcel/Shared/trend/trendClass.php
Executable file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPExcel
|
||||
*
|
||||
* Copyright (c) 2006 - 2014 PHPExcel
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
|
||||
* @version 1.8.0, 2014-03-02
|
||||
*/
|
||||
|
||||
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php';
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php';
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php';
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php';
|
||||
require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php';
|
||||
|
||||
|
||||
/**
|
||||
* PHPExcel_trendClass
|
||||
*
|
||||
* @category PHPExcel
|
||||
* @package PHPExcel_Shared_Trend
|
||||
* @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
|
||||
*/
|
||||
class trendClass
|
||||
{
|
||||
const TREND_LINEAR = 'Linear';
|
||||
const TREND_LOGARITHMIC = 'Logarithmic';
|
||||
const TREND_EXPONENTIAL = 'Exponential';
|
||||
const TREND_POWER = 'Power';
|
||||
const TREND_POLYNOMIAL_2 = 'Polynomial_2';
|
||||
const TREND_POLYNOMIAL_3 = 'Polynomial_3';
|
||||
const TREND_POLYNOMIAL_4 = 'Polynomial_4';
|
||||
const TREND_POLYNOMIAL_5 = 'Polynomial_5';
|
||||
const TREND_POLYNOMIAL_6 = 'Polynomial_6';
|
||||
const TREND_BEST_FIT = 'Bestfit';
|
||||
const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials';
|
||||
|
||||
/**
|
||||
* Names of the best-fit trend analysis methods
|
||||
*
|
||||
* @var string[]
|
||||
**/
|
||||
private static $_trendTypes = array( self::TREND_LINEAR,
|
||||
self::TREND_LOGARITHMIC,
|
||||
self::TREND_EXPONENTIAL,
|
||||
self::TREND_POWER
|
||||
);
|
||||
/**
|
||||
* Names of the best-fit trend polynomial orders
|
||||
*
|
||||
* @var string[]
|
||||
**/
|
||||
private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2,
|
||||
self::TREND_POLYNOMIAL_3,
|
||||
self::TREND_POLYNOMIAL_4,
|
||||
self::TREND_POLYNOMIAL_5,
|
||||
self::TREND_POLYNOMIAL_6
|
||||
);
|
||||
|
||||
/**
|
||||
* Cached results for each method when trying to identify which provides the best fit
|
||||
*
|
||||
* @var PHPExcel_Best_Fit[]
|
||||
**/
|
||||
private static $_trendCache = array();
|
||||
|
||||
|
||||
public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) {
|
||||
// Calculate number of points in each dataset
|
||||
$nY = count($yValues);
|
||||
$nX = count($xValues);
|
||||
|
||||
// Define X Values if necessary
|
||||
if ($nX == 0) {
|
||||
$xValues = range(1,$nY);
|
||||
$nX = $nY;
|
||||
} elseif ($nY != $nX) {
|
||||
// Ensure both arrays of points are the same size
|
||||
trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
$key = md5($trendType.$const.serialize($yValues).serialize($xValues));
|
||||
// Determine which trend method has been requested
|
||||
switch ($trendType) {
|
||||
// Instantiate and return the class for the requested trend method
|
||||
case self::TREND_LINEAR :
|
||||
case self::TREND_LOGARITHMIC :
|
||||
case self::TREND_EXPONENTIAL :
|
||||
case self::TREND_POWER :
|
||||
if (!isset(self::$_trendCache[$key])) {
|
||||
$className = 'PHPExcel_'.$trendType.'_Best_Fit';
|
||||
self::$_trendCache[$key] = new $className($yValues,$xValues,$const);
|
||||
}
|
||||
return self::$_trendCache[$key];
|
||||
break;
|
||||
case self::TREND_POLYNOMIAL_2 :
|
||||
case self::TREND_POLYNOMIAL_3 :
|
||||
case self::TREND_POLYNOMIAL_4 :
|
||||
case self::TREND_POLYNOMIAL_5 :
|
||||
case self::TREND_POLYNOMIAL_6 :
|
||||
if (!isset(self::$_trendCache[$key])) {
|
||||
$order = substr($trendType,-1);
|
||||
self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);
|
||||
}
|
||||
return self::$_trendCache[$key];
|
||||
break;
|
||||
case self::TREND_BEST_FIT :
|
||||
case self::TREND_BEST_FIT_NO_POLY :
|
||||
// If the request is to determine the best fit regression, then we test each trend line in turn
|
||||
// Start by generating an instance of each available trend method
|
||||
foreach(self::$_trendTypes as $trendMethod) {
|
||||
$className = 'PHPExcel_'.$trendMethod.'BestFit';
|
||||
$bestFit[$trendMethod] = new $className($yValues,$xValues,$const);
|
||||
$bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
|
||||
}
|
||||
if ($trendType != self::TREND_BEST_FIT_NO_POLY) {
|
||||
foreach(self::$_trendTypePolyOrders as $trendMethod) {
|
||||
$order = substr($trendMethod,-1);
|
||||
$bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);
|
||||
if ($bestFit[$trendMethod]->getError()) {
|
||||
unset($bestFit[$trendMethod]);
|
||||
} else {
|
||||
$bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Determine which of our trend lines is the best fit, and then we return the instance of that trend class
|
||||
arsort($bestFitValue);
|
||||
$bestFitType = key($bestFitValue);
|
||||
return $bestFit[$bestFitType];
|
||||
break;
|
||||
default :
|
||||
return false;
|
||||
}
|
||||
} // function calculate()
|
||||
|
||||
} // class trendClass
|
Reference in New Issue
Block a user