作者 SHW\戥岁。。

跨域

正在显示 22 个修改的文件 包含 4699 行增加0 行删除

要显示太多修改。

为保证性能只显示 22 of 22+ 个文件。

  1 +/Build export-ignore
  2 +/unitTests export-ignore
  3 +README.md export-ignore
  1 +build/PHPExcel.phar
  2 +unitTests/codeCoverage
  3 +analysis
  4 +
  5 +## IDE support
  6 +*.buildpath
  7 +*.project
  8 +/.settings
  9 +/.idea
  1 +language: php
  2 +
  3 +php:
  4 + - 5.4
  5 + - 5.5
  6 + - 5.6
  7 + - 7.0
  8 + - hhvm
  9 +
  10 +matrix:
  11 + allow_failures:
  12 + - php: hhvm
  13 +
  14 +before_script:
  15 + ## Packages
  16 + - sudo apt-get -qq update > /dev/null
  17 + ## Composer
  18 + - composer self-update
  19 + - composer install --prefer-source --dev
  20 + - phpenv global "$TRAVIS_PHP_VERSION"
  21 +
  22 +script:
  23 + ## PHP_CodeSniffer
  24 + - ./vendor/bin/phpcs --report-width=200 --report-summary --report-full Classes/ unitTests/ --standard=PSR2 -n
  25 + ## PHPUnit
  26 + - phpunit -c ./unitTests/
  27 +
  28 +notifications:
  29 + email: false
  1 +<?php
  2 +
  3 +/** PHPExcel root directory */
  4 +if (!defined('PHPEXCEL_ROOT')) {
  5 + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');
  6 + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');
  7 +}
  8 +
  9 +/**
  10 + * PHPExcel
  11 + *
  12 + * Copyright (c) 2006 - 2015 PHPExcel
  13 + *
  14 + * This library is free software; you can redistribute it and/or
  15 + * modify it under the terms of the GNU Lesser General Public
  16 + * License as published by the Free Software Foundation; either
  17 + * version 2.1 of the License, or (at your option) any later version.
  18 + *
  19 + * This library is distributed in the hope that it will be useful,
  20 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22 + * Lesser General Public License for more details.
  23 + *
  24 + * You should have received a copy of the GNU Lesser General Public
  25 + * License along with this library; if not, write to the Free Software
  26 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  27 + *
  28 + * @category PHPExcel
  29 + * @package PHPExcel
  30 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  31 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  32 + * @version ##VERSION##, ##DATE##
  33 + */
  34 +class PHPExcel
  35 +{
  36 + /**
  37 + * Unique ID
  38 + *
  39 + * @var string
  40 + */
  41 + private $uniqueID;
  42 +
  43 + /**
  44 + * Document properties
  45 + *
  46 + * @var PHPExcel_DocumentProperties
  47 + */
  48 + private $properties;
  49 +
  50 + /**
  51 + * Document security
  52 + *
  53 + * @var PHPExcel_DocumentSecurity
  54 + */
  55 + private $security;
  56 +
  57 + /**
  58 + * Collection of Worksheet objects
  59 + *
  60 + * @var PHPExcel_Worksheet[]
  61 + */
  62 + private $workSheetCollection = array();
  63 +
  64 + /**
  65 + * Calculation Engine
  66 + *
  67 + * @var PHPExcel_Calculation
  68 + */
  69 + private $calculationEngine;
  70 +
  71 + /**
  72 + * Active sheet index
  73 + *
  74 + * @var integer
  75 + */
  76 + private $activeSheetIndex = 0;
  77 +
  78 + /**
  79 + * Named ranges
  80 + *
  81 + * @var PHPExcel_NamedRange[]
  82 + */
  83 + private $namedRanges = array();
  84 +
  85 + /**
  86 + * CellXf supervisor
  87 + *
  88 + * @var PHPExcel_Style
  89 + */
  90 + private $cellXfSupervisor;
  91 +
  92 + /**
  93 + * CellXf collection
  94 + *
  95 + * @var PHPExcel_Style[]
  96 + */
  97 + private $cellXfCollection = array();
  98 +
  99 + /**
  100 + * CellStyleXf collection
  101 + *
  102 + * @var PHPExcel_Style[]
  103 + */
  104 + private $cellStyleXfCollection = array();
  105 +
  106 + /**
  107 + * hasMacros : this workbook have macros ?
  108 + *
  109 + * @var bool
  110 + */
  111 + private $hasMacros = false;
  112 +
  113 + /**
  114 + * macrosCode : all macros code (the vbaProject.bin file, this include form, code, etc.), null if no macro
  115 + *
  116 + * @var binary
  117 + */
  118 + private $macrosCode;
  119 + /**
  120 + * macrosCertificate : if macros are signed, contains vbaProjectSignature.bin file, null if not signed
  121 + *
  122 + * @var binary
  123 + */
  124 + private $macrosCertificate;
  125 +
  126 + /**
  127 + * ribbonXMLData : null if workbook is'nt Excel 2007 or not contain a customized UI
  128 + *
  129 + * @var null|string
  130 + */
  131 + private $ribbonXMLData;
  132 +
  133 + /**
  134 + * ribbonBinObjects : null if workbook is'nt Excel 2007 or not contain embedded objects (picture(s)) for Ribbon Elements
  135 + * ignored if $ribbonXMLData is null
  136 + *
  137 + * @var null|array
  138 + */
  139 + private $ribbonBinObjects;
  140 +
  141 + /**
  142 + * The workbook has macros ?
  143 + *
  144 + * @return boolean true if workbook has macros, false if not
  145 + */
  146 + public function hasMacros()
  147 + {
  148 + return $this->hasMacros;
  149 + }
  150 +
  151 + /**
  152 + * Define if a workbook has macros
  153 + *
  154 + * @param boolean $hasMacros true|false
  155 + */
  156 + public function setHasMacros($hasMacros = false)
  157 + {
  158 + $this->hasMacros = (bool) $hasMacros;
  159 + }
  160 +
  161 + /**
  162 + * Set the macros code
  163 + *
  164 + * @param string $MacrosCode string|null
  165 + */
  166 + public function setMacrosCode($MacrosCode = null)
  167 + {
  168 + $this->macrosCode=$MacrosCode;
  169 + $this->setHasMacros(!is_null($MacrosCode));
  170 + }
  171 +
  172 + /**
  173 + * Return the macros code
  174 + *
  175 + * @return string|null
  176 + */
  177 + public function getMacrosCode()
  178 + {
  179 + return $this->macrosCode;
  180 + }
  181 +
  182 + /**
  183 + * Set the macros certificate
  184 + *
  185 + * @param string|null $Certificate
  186 + */
  187 + public function setMacrosCertificate($Certificate = null)
  188 + {
  189 + $this->macrosCertificate=$Certificate;
  190 + }
  191 +
  192 + /**
  193 + * Is the project signed ?
  194 + *
  195 + * @return boolean true|false
  196 + */
  197 + public function hasMacrosCertificate()
  198 + {
  199 + return !is_null($this->macrosCertificate);
  200 + }
  201 +
  202 + /**
  203 + * Return the macros certificate
  204 + *
  205 + * @return string|null
  206 + */
  207 + public function getMacrosCertificate()
  208 + {
  209 + return $this->macrosCertificate;
  210 + }
  211 +
  212 + /**
  213 + * Remove all macros, certificate from spreadsheet
  214 + *
  215 + */
  216 + public function discardMacros()
  217 + {
  218 + $this->hasMacros=false;
  219 + $this->macrosCode=null;
  220 + $this->macrosCertificate=null;
  221 + }
  222 +
  223 + /**
  224 + * set ribbon XML data
  225 + *
  226 + */
  227 + public function setRibbonXMLData($Target = null, $XMLData = null)
  228 + {
  229 + if (!is_null($Target) && !is_null($XMLData)) {
  230 + $this->ribbonXMLData = array('target' => $Target, 'data' => $XMLData);
  231 + } else {
  232 + $this->ribbonXMLData = null;
  233 + }
  234 + }
  235 +
  236 + /**
  237 + * retrieve ribbon XML Data
  238 + *
  239 + * return string|null|array
  240 + */
  241 + public function getRibbonXMLData($What = 'all') //we need some constants here...
  242 + {
  243 + $ReturnData = null;
  244 + $What = strtolower($What);
  245 + switch ($What){
  246 + case 'all':
  247 + $ReturnData = $this->ribbonXMLData;
  248 + break;
  249 + case 'target':
  250 + case 'data':
  251 + if (is_array($this->ribbonXMLData) && array_key_exists($What, $this->ribbonXMLData)) {
  252 + $ReturnData = $this->ribbonXMLData[$What];
  253 + }
  254 + break;
  255 + }
  256 +
  257 + return $ReturnData;
  258 + }
  259 +
  260 + /**
  261 + * store binaries ribbon objects (pictures)
  262 + *
  263 + */
  264 + public function setRibbonBinObjects($BinObjectsNames = null, $BinObjectsData = null)
  265 + {
  266 + if (!is_null($BinObjectsNames) && !is_null($BinObjectsData)) {
  267 + $this->ribbonBinObjects = array('names' => $BinObjectsNames, 'data' => $BinObjectsData);
  268 + } else {
  269 + $this->ribbonBinObjects = null;
  270 + }
  271 + }
  272 + /**
  273 + * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function)
  274 + *
  275 + */
  276 + private function getExtensionOnly($ThePath)
  277 + {
  278 + return pathinfo($ThePath, PATHINFO_EXTENSION);
  279 + }
  280 +
  281 + /**
  282 + * retrieve Binaries Ribbon Objects
  283 + *
  284 + */
  285 + public function getRibbonBinObjects($What = 'all')
  286 + {
  287 + $ReturnData = null;
  288 + $What = strtolower($What);
  289 + switch($What) {
  290 + case 'all':
  291 + return $this->ribbonBinObjects;
  292 + break;
  293 + case 'names':
  294 + case 'data':
  295 + if (is_array($this->ribbonBinObjects) && array_key_exists($What, $this->ribbonBinObjects)) {
  296 + $ReturnData=$this->ribbonBinObjects[$What];
  297 + }
  298 + break;
  299 + case 'types':
  300 + if (is_array($this->ribbonBinObjects) &&
  301 + array_key_exists('data', $this->ribbonBinObjects) && is_array($this->ribbonBinObjects['data'])) {
  302 + $tmpTypes=array_keys($this->ribbonBinObjects['data']);
  303 + $ReturnData = array_unique(array_map(array($this, 'getExtensionOnly'), $tmpTypes));
  304 + } else {
  305 + $ReturnData=array(); // the caller want an array... not null if empty
  306 + }
  307 + break;
  308 + }
  309 + return $ReturnData;
  310 + }
  311 +
  312 + /**
  313 + * This workbook have a custom UI ?
  314 + *
  315 + * @return boolean true|false
  316 + */
  317 + public function hasRibbon()
  318 + {
  319 + return !is_null($this->ribbonXMLData);
  320 + }
  321 +
  322 + /**
  323 + * This workbook have additionnal object for the ribbon ?
  324 + *
  325 + * @return boolean true|false
  326 + */
  327 + public function hasRibbonBinObjects()
  328 + {
  329 + return !is_null($this->ribbonBinObjects);
  330 + }
  331 +
  332 + /**
  333 + * Check if a sheet with a specified code name already exists
  334 + *
  335 + * @param string $pSheetCodeName Name of the worksheet to check
  336 + * @return boolean
  337 + */
  338 + public function sheetCodeNameExists($pSheetCodeName)
  339 + {
  340 + return ($this->getSheetByCodeName($pSheetCodeName) !== null);
  341 + }
  342 +
  343 + /**
  344 + * Get sheet by code name. Warning : sheet don't have always a code name !
  345 + *
  346 + * @param string $pName Sheet name
  347 + * @return PHPExcel_Worksheet
  348 + */
  349 + public function getSheetByCodeName($pName = '')
  350 + {
  351 + $worksheetCount = count($this->workSheetCollection);
  352 + for ($i = 0; $i < $worksheetCount; ++$i) {
  353 + if ($this->workSheetCollection[$i]->getCodeName() == $pName) {
  354 + return $this->workSheetCollection[$i];
  355 + }
  356 + }
  357 +
  358 + return null;
  359 + }
  360 +
  361 + /**
  362 + * Create a new PHPExcel with one Worksheet
  363 + */
  364 + public function __construct()
  365 + {
  366 + $this->uniqueID = uniqid();
  367 + $this->calculationEngine = new PHPExcel_Calculation($this);
  368 +
  369 + // Initialise worksheet collection and add one worksheet
  370 + $this->workSheetCollection = array();
  371 + $this->workSheetCollection[] = new PHPExcel_Worksheet($this);
  372 + $this->activeSheetIndex = 0;
  373 +
  374 + // Create document properties
  375 + $this->properties = new PHPExcel_DocumentProperties();
  376 +
  377 + // Create document security
  378 + $this->security = new PHPExcel_DocumentSecurity();
  379 +
  380 + // Set named ranges
  381 + $this->namedRanges = array();
  382 +
  383 + // Create the cellXf supervisor
  384 + $this->cellXfSupervisor = new PHPExcel_Style(true);
  385 + $this->cellXfSupervisor->bindParent($this);
  386 +
  387 + // Create the default style
  388 + $this->addCellXf(new PHPExcel_Style);
  389 + $this->addCellStyleXf(new PHPExcel_Style);
  390 + }
  391 +
  392 + /**
  393 + * Code to execute when this worksheet is unset()
  394 + *
  395 + */
  396 + public function __destruct()
  397 + {
  398 + $this->calculationEngine = null;
  399 + $this->disconnectWorksheets();
  400 + }
  401 +
  402 + /**
  403 + * Disconnect all worksheets from this PHPExcel workbook object,
  404 + * typically so that the PHPExcel object can be unset
  405 + *
  406 + */
  407 + public function disconnectWorksheets()
  408 + {
  409 + $worksheet = null;
  410 + foreach ($this->workSheetCollection as $k => &$worksheet) {
  411 + $worksheet->disconnectCells();
  412 + $this->workSheetCollection[$k] = null;
  413 + }
  414 + unset($worksheet);
  415 + $this->workSheetCollection = array();
  416 + }
  417 +
  418 + /**
  419 + * Return the calculation engine for this worksheet
  420 + *
  421 + * @return PHPExcel_Calculation
  422 + */
  423 + public function getCalculationEngine()
  424 + {
  425 + return $this->calculationEngine;
  426 + } // function getCellCacheController()
  427 +
  428 + /**
  429 + * Get properties
  430 + *
  431 + * @return PHPExcel_DocumentProperties
  432 + */
  433 + public function getProperties()
  434 + {
  435 + return $this->properties;
  436 + }
  437 +
  438 + /**
  439 + * Set properties
  440 + *
  441 + * @param PHPExcel_DocumentProperties $pValue
  442 + */
  443 + public function setProperties(PHPExcel_DocumentProperties $pValue)
  444 + {
  445 + $this->properties = $pValue;
  446 + }
  447 +
  448 + /**
  449 + * Get security
  450 + *
  451 + * @return PHPExcel_DocumentSecurity
  452 + */
  453 + public function getSecurity()
  454 + {
  455 + return $this->security;
  456 + }
  457 +
  458 + /**
  459 + * Set security
  460 + *
  461 + * @param PHPExcel_DocumentSecurity $pValue
  462 + */
  463 + public function setSecurity(PHPExcel_DocumentSecurity $pValue)
  464 + {
  465 + $this->security = $pValue;
  466 + }
  467 +
  468 + /**
  469 + * Get active sheet
  470 + *
  471 + * @return PHPExcel_Worksheet
  472 + *
  473 + * @throws PHPExcel_Exception
  474 + */
  475 + public function getActiveSheet()
  476 + {
  477 + return $this->getSheet($this->activeSheetIndex);
  478 + }
  479 +
  480 + /**
  481 + * Create sheet and add it to this workbook
  482 + *
  483 + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
  484 + * @return PHPExcel_Worksheet
  485 + * @throws PHPExcel_Exception
  486 + */
  487 + public function createSheet($iSheetIndex = null)
  488 + {
  489 + $newSheet = new PHPExcel_Worksheet($this);
  490 + $this->addSheet($newSheet, $iSheetIndex);
  491 + return $newSheet;
  492 + }
  493 +
  494 + /**
  495 + * Check if a sheet with a specified name already exists
  496 + *
  497 + * @param string $pSheetName Name of the worksheet to check
  498 + * @return boolean
  499 + */
  500 + public function sheetNameExists($pSheetName)
  501 + {
  502 + return ($this->getSheetByName($pSheetName) !== null);
  503 + }
  504 +
  505 + /**
  506 + * Add sheet
  507 + *
  508 + * @param PHPExcel_Worksheet $pSheet
  509 + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
  510 + * @return PHPExcel_Worksheet
  511 + * @throws PHPExcel_Exception
  512 + */
  513 + public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null)
  514 + {
  515 + if ($this->sheetNameExists($pSheet->getTitle())) {
  516 + throw new PHPExcel_Exception(
  517 + "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first."
  518 + );
  519 + }
  520 +
  521 + if ($iSheetIndex === null) {
  522 + if ($this->activeSheetIndex < 0) {
  523 + $this->activeSheetIndex = 0;
  524 + }
  525 + $this->workSheetCollection[] = $pSheet;
  526 + } else {
  527 + // Insert the sheet at the requested index
  528 + array_splice(
  529 + $this->workSheetCollection,
  530 + $iSheetIndex,
  531 + 0,
  532 + array($pSheet)
  533 + );
  534 +
  535 + // Adjust active sheet index if necessary
  536 + if ($this->activeSheetIndex >= $iSheetIndex) {
  537 + ++$this->activeSheetIndex;
  538 + }
  539 + }
  540 +
  541 + if ($pSheet->getParent() === null) {
  542 + $pSheet->rebindParent($this);
  543 + }
  544 +
  545 + return $pSheet;
  546 + }
  547 +
  548 + /**
  549 + * Remove sheet by index
  550 + *
  551 + * @param int $pIndex Active sheet index
  552 + * @throws PHPExcel_Exception
  553 + */
  554 + public function removeSheetByIndex($pIndex = 0)
  555 + {
  556 +
  557 + $numSheets = count($this->workSheetCollection);
  558 + if ($pIndex > $numSheets - 1) {
  559 + throw new PHPExcel_Exception(
  560 + "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
  561 + );
  562 + } else {
  563 + array_splice($this->workSheetCollection, $pIndex, 1);
  564 + }
  565 + // Adjust active sheet index if necessary
  566 + if (($this->activeSheetIndex >= $pIndex) &&
  567 + ($pIndex > count($this->workSheetCollection) - 1)) {
  568 + --$this->activeSheetIndex;
  569 + }
  570 +
  571 + }
  572 +
  573 + /**
  574 + * Get sheet by index
  575 + *
  576 + * @param int $pIndex Sheet index
  577 + * @return PHPExcel_Worksheet
  578 + * @throws PHPExcel_Exception
  579 + */
  580 + public function getSheet($pIndex = 0)
  581 + {
  582 + if (!isset($this->workSheetCollection[$pIndex])) {
  583 + $numSheets = $this->getSheetCount();
  584 + throw new PHPExcel_Exception(
  585 + "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}."
  586 + );
  587 + }
  588 +
  589 + return $this->workSheetCollection[$pIndex];
  590 + }
  591 +
  592 + /**
  593 + * Get all sheets
  594 + *
  595 + * @return PHPExcel_Worksheet[]
  596 + */
  597 + public function getAllSheets()
  598 + {
  599 + return $this->workSheetCollection;
  600 + }
  601 +
  602 + /**
  603 + * Get sheet by name
  604 + *
  605 + * @param string $pName Sheet name
  606 + * @return PHPExcel_Worksheet
  607 + */
  608 + public function getSheetByName($pName = '')
  609 + {
  610 + $worksheetCount = count($this->workSheetCollection);
  611 + for ($i = 0; $i < $worksheetCount; ++$i) {
  612 + if ($this->workSheetCollection[$i]->getTitle() === $pName) {
  613 + return $this->workSheetCollection[$i];
  614 + }
  615 + }
  616 +
  617 + return null;
  618 + }
  619 +
  620 + /**
  621 + * Get index for sheet
  622 + *
  623 + * @param PHPExcel_Worksheet $pSheet
  624 + * @return int Sheet index
  625 + * @throws PHPExcel_Exception
  626 + */
  627 + public function getIndex(PHPExcel_Worksheet $pSheet)
  628 + {
  629 + foreach ($this->workSheetCollection as $key => $value) {
  630 + if ($value->getHashCode() == $pSheet->getHashCode()) {
  631 + return $key;
  632 + }
  633 + }
  634 +
  635 + throw new PHPExcel_Exception("Sheet does not exist.");
  636 + }
  637 +
  638 + /**
  639 + * Set index for sheet by sheet name.
  640 + *
  641 + * @param string $sheetName Sheet name to modify index for
  642 + * @param int $newIndex New index for the sheet
  643 + * @return int New sheet index
  644 + * @throws PHPExcel_Exception
  645 + */
  646 + public function setIndexByName($sheetName, $newIndex)
  647 + {
  648 + $oldIndex = $this->getIndex($this->getSheetByName($sheetName));
  649 + $pSheet = array_splice(
  650 + $this->workSheetCollection,
  651 + $oldIndex,
  652 + 1
  653 + );
  654 + array_splice(
  655 + $this->workSheetCollection,
  656 + $newIndex,
  657 + 0,
  658 + $pSheet
  659 + );
  660 + return $newIndex;
  661 + }
  662 +
  663 + /**
  664 + * Get sheet count
  665 + *
  666 + * @return int
  667 + */
  668 + public function getSheetCount()
  669 + {
  670 + return count($this->workSheetCollection);
  671 + }
  672 +
  673 + /**
  674 + * Get active sheet index
  675 + *
  676 + * @return int Active sheet index
  677 + */
  678 + public function getActiveSheetIndex()
  679 + {
  680 + return $this->activeSheetIndex;
  681 + }
  682 +
  683 + /**
  684 + * Set active sheet index
  685 + *
  686 + * @param int $pIndex Active sheet index
  687 + * @throws PHPExcel_Exception
  688 + * @return PHPExcel_Worksheet
  689 + */
  690 + public function setActiveSheetIndex($pIndex = 0)
  691 + {
  692 + $numSheets = count($this->workSheetCollection);
  693 +
  694 + if ($pIndex > $numSheets - 1) {
  695 + throw new PHPExcel_Exception(
  696 + "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}."
  697 + );
  698 + } else {
  699 + $this->activeSheetIndex = $pIndex;
  700 + }
  701 + return $this->getActiveSheet();
  702 + }
  703 +
  704 + /**
  705 + * Set active sheet index by name
  706 + *
  707 + * @param string $pValue Sheet title
  708 + * @return PHPExcel_Worksheet
  709 + * @throws PHPExcel_Exception
  710 + */
  711 + public function setActiveSheetIndexByName($pValue = '')
  712 + {
  713 + if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) {
  714 + $this->setActiveSheetIndex($this->getIndex($worksheet));
  715 + return $worksheet;
  716 + }
  717 +
  718 + throw new PHPExcel_Exception('Workbook does not contain sheet:' . $pValue);
  719 + }
  720 +
  721 + /**
  722 + * Get sheet names
  723 + *
  724 + * @return string[]
  725 + */
  726 + public function getSheetNames()
  727 + {
  728 + $returnValue = array();
  729 + $worksheetCount = $this->getSheetCount();
  730 + for ($i = 0; $i < $worksheetCount; ++$i) {
  731 + $returnValue[] = $this->getSheet($i)->getTitle();
  732 + }
  733 +
  734 + return $returnValue;
  735 + }
  736 +
  737 + /**
  738 + * Add external sheet
  739 + *
  740 + * @param PHPExcel_Worksheet $pSheet External sheet to add
  741 + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)
  742 + * @throws PHPExcel_Exception
  743 + * @return PHPExcel_Worksheet
  744 + */
  745 + public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null)
  746 + {
  747 + if ($this->sheetNameExists($pSheet->getTitle())) {
  748 + throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.");
  749 + }
  750 +
  751 + // count how many cellXfs there are in this workbook currently, we will need this below
  752 + $countCellXfs = count($this->cellXfCollection);
  753 +
  754 + // copy all the shared cellXfs from the external workbook and append them to the current
  755 + foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) {
  756 + $this->addCellXf(clone $cellXf);
  757 + }
  758 +
  759 + // move sheet to this workbook
  760 + $pSheet->rebindParent($this);
  761 +
  762 + // update the cellXfs
  763 + foreach ($pSheet->getCellCollection(false) as $cellID) {
  764 + $cell = $pSheet->getCell($cellID);
  765 + $cell->setXfIndex($cell->getXfIndex() + $countCellXfs);
  766 + }
  767 +
  768 + return $this->addSheet($pSheet, $iSheetIndex);
  769 + }
  770 +
  771 + /**
  772 + * Get named ranges
  773 + *
  774 + * @return PHPExcel_NamedRange[]
  775 + */
  776 + public function getNamedRanges()
  777 + {
  778 + return $this->namedRanges;
  779 + }
  780 +
  781 + /**
  782 + * Add named range
  783 + *
  784 + * @param PHPExcel_NamedRange $namedRange
  785 + * @return boolean
  786 + */
  787 + public function addNamedRange(PHPExcel_NamedRange $namedRange)
  788 + {
  789 + if ($namedRange->getScope() == null) {
  790 + // global scope
  791 + $this->namedRanges[$namedRange->getName()] = $namedRange;
  792 + } else {
  793 + // local scope
  794 + $this->namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange;
  795 + }
  796 + return true;
  797 + }
  798 +
  799 + /**
  800 + * Get named range
  801 + *
  802 + * @param string $namedRange
  803 + * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope
  804 + * @return PHPExcel_NamedRange|null
  805 + */
  806 + public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null)
  807 + {
  808 + $returnValue = null;
  809 +
  810 + if ($namedRange != '' && ($namedRange !== null)) {
  811 + // first look for global defined name
  812 + if (isset($this->namedRanges[$namedRange])) {
  813 + $returnValue = $this->namedRanges[$namedRange];
  814 + }
  815 +
  816 + // then look for local defined name (has priority over global defined name if both names exist)
  817 + if (($pSheet !== null) && isset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
  818 + $returnValue = $this->namedRanges[$pSheet->getTitle() . '!' . $namedRange];
  819 + }
  820 + }
  821 +
  822 + return $returnValue;
  823 + }
  824 +
  825 + /**
  826 + * Remove named range
  827 + *
  828 + * @param string $namedRange
  829 + * @param PHPExcel_Worksheet|null $pSheet Scope: use null for global scope.
  830 + * @return PHPExcel
  831 + */
  832 + public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null)
  833 + {
  834 + if ($pSheet === null) {
  835 + if (isset($this->namedRanges[$namedRange])) {
  836 + unset($this->namedRanges[$namedRange]);
  837 + }
  838 + } else {
  839 + if (isset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {
  840 + unset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange]);
  841 + }
  842 + }
  843 + return $this;
  844 + }
  845 +
  846 + /**
  847 + * Get worksheet iterator
  848 + *
  849 + * @return PHPExcel_WorksheetIterator
  850 + */
  851 + public function getWorksheetIterator()
  852 + {
  853 + return new PHPExcel_WorksheetIterator($this);
  854 + }
  855 +
  856 + /**
  857 + * Copy workbook (!= clone!)
  858 + *
  859 + * @return PHPExcel
  860 + */
  861 + public function copy()
  862 + {
  863 + $copied = clone $this;
  864 +
  865 + $worksheetCount = count($this->workSheetCollection);
  866 + for ($i = 0; $i < $worksheetCount; ++$i) {
  867 + $this->workSheetCollection[$i] = $this->workSheetCollection[$i]->copy();
  868 + $this->workSheetCollection[$i]->rebindParent($this);
  869 + }
  870 +
  871 + return $copied;
  872 + }
  873 +
  874 + /**
  875 + * Implement PHP __clone to create a deep clone, not just a shallow copy.
  876 + */
  877 + public function __clone()
  878 + {
  879 + foreach ($this as $key => $val) {
  880 + if (is_object($val) || (is_array($val))) {
  881 + $this->{$key} = unserialize(serialize($val));
  882 + }
  883 + }
  884 + }
  885 +
  886 + /**
  887 + * Get the workbook collection of cellXfs
  888 + *
  889 + * @return PHPExcel_Style[]
  890 + */
  891 + public function getCellXfCollection()
  892 + {
  893 + return $this->cellXfCollection;
  894 + }
  895 +
  896 + /**
  897 + * Get cellXf by index
  898 + *
  899 + * @param int $pIndex
  900 + * @return PHPExcel_Style
  901 + */
  902 + public function getCellXfByIndex($pIndex = 0)
  903 + {
  904 + return $this->cellXfCollection[$pIndex];
  905 + }
  906 +
  907 + /**
  908 + * Get cellXf by hash code
  909 + *
  910 + * @param string $pValue
  911 + * @return PHPExcel_Style|boolean False if no match found
  912 + */
  913 + public function getCellXfByHashCode($pValue = '')
  914 + {
  915 + foreach ($this->cellXfCollection as $cellXf) {
  916 + if ($cellXf->getHashCode() == $pValue) {
  917 + return $cellXf;
  918 + }
  919 + }
  920 + return false;
  921 + }
  922 +
  923 + /**
  924 + * Check if style exists in style collection
  925 + *
  926 + * @param PHPExcel_Style $pCellStyle
  927 + * @return boolean
  928 + */
  929 + public function cellXfExists($pCellStyle = null)
  930 + {
  931 + return in_array($pCellStyle, $this->cellXfCollection, true);
  932 + }
  933 +
  934 + /**
  935 + * Get default style
  936 + *
  937 + * @return PHPExcel_Style
  938 + * @throws PHPExcel_Exception
  939 + */
  940 + public function getDefaultStyle()
  941 + {
  942 + if (isset($this->cellXfCollection[0])) {
  943 + return $this->cellXfCollection[0];
  944 + }
  945 + throw new PHPExcel_Exception('No default style found for this workbook');
  946 + }
  947 +
  948 + /**
  949 + * Add a cellXf to the workbook
  950 + *
  951 + * @param PHPExcel_Style $style
  952 + */
  953 + public function addCellXf(PHPExcel_Style $style)
  954 + {
  955 + $this->cellXfCollection[] = $style;
  956 + $style->setIndex(count($this->cellXfCollection) - 1);
  957 + }
  958 +
  959 + /**
  960 + * Remove cellXf by index. It is ensured that all cells get their xf index updated.
  961 + *
  962 + * @param integer $pIndex Index to cellXf
  963 + * @throws PHPExcel_Exception
  964 + */
  965 + public function removeCellXfByIndex($pIndex = 0)
  966 + {
  967 + if ($pIndex > count($this->cellXfCollection) - 1) {
  968 + throw new PHPExcel_Exception("CellXf index is out of bounds.");
  969 + } else {
  970 + // first remove the cellXf
  971 + array_splice($this->cellXfCollection, $pIndex, 1);
  972 +
  973 + // then update cellXf indexes for cells
  974 + foreach ($this->workSheetCollection as $worksheet) {
  975 + foreach ($worksheet->getCellCollection(false) as $cellID) {
  976 + $cell = $worksheet->getCell($cellID);
  977 + $xfIndex = $cell->getXfIndex();
  978 + if ($xfIndex > $pIndex) {
  979 + // decrease xf index by 1
  980 + $cell->setXfIndex($xfIndex - 1);
  981 + } elseif ($xfIndex == $pIndex) {
  982 + // set to default xf index 0
  983 + $cell->setXfIndex(0);
  984 + }
  985 + }
  986 + }
  987 + }
  988 + }
  989 +
  990 + /**
  991 + * Get the cellXf supervisor
  992 + *
  993 + * @return PHPExcel_Style
  994 + */
  995 + public function getCellXfSupervisor()
  996 + {
  997 + return $this->cellXfSupervisor;
  998 + }
  999 +
  1000 + /**
  1001 + * Get the workbook collection of cellStyleXfs
  1002 + *
  1003 + * @return PHPExcel_Style[]
  1004 + */
  1005 + public function getCellStyleXfCollection()
  1006 + {
  1007 + return $this->cellStyleXfCollection;
  1008 + }
  1009 +
  1010 + /**
  1011 + * Get cellStyleXf by index
  1012 + *
  1013 + * @param integer $pIndex Index to cellXf
  1014 + * @return PHPExcel_Style
  1015 + */
  1016 + public function getCellStyleXfByIndex($pIndex = 0)
  1017 + {
  1018 + return $this->cellStyleXfCollection[$pIndex];
  1019 + }
  1020 +
  1021 + /**
  1022 + * Get cellStyleXf by hash code
  1023 + *
  1024 + * @param string $pValue
  1025 + * @return PHPExcel_Style|boolean False if no match found
  1026 + */
  1027 + public function getCellStyleXfByHashCode($pValue = '')
  1028 + {
  1029 + foreach ($this->cellStyleXfCollection as $cellStyleXf) {
  1030 + if ($cellStyleXf->getHashCode() == $pValue) {
  1031 + return $cellStyleXf;
  1032 + }
  1033 + }
  1034 + return false;
  1035 + }
  1036 +
  1037 + /**
  1038 + * Add a cellStyleXf to the workbook
  1039 + *
  1040 + * @param PHPExcel_Style $pStyle
  1041 + */
  1042 + public function addCellStyleXf(PHPExcel_Style $pStyle)
  1043 + {
  1044 + $this->cellStyleXfCollection[] = $pStyle;
  1045 + $pStyle->setIndex(count($this->cellStyleXfCollection) - 1);
  1046 + }
  1047 +
  1048 + /**
  1049 + * Remove cellStyleXf by index
  1050 + *
  1051 + * @param integer $pIndex Index to cellXf
  1052 + * @throws PHPExcel_Exception
  1053 + */
  1054 + public function removeCellStyleXfByIndex($pIndex = 0)
  1055 + {
  1056 + if ($pIndex > count($this->cellStyleXfCollection) - 1) {
  1057 + throw new PHPExcel_Exception("CellStyleXf index is out of bounds.");
  1058 + } else {
  1059 + array_splice($this->cellStyleXfCollection, $pIndex, 1);
  1060 + }
  1061 + }
  1062 +
  1063 + /**
  1064 + * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells
  1065 + * and columns in the workbook
  1066 + */
  1067 + public function garbageCollect()
  1068 + {
  1069 + // how many references are there to each cellXf ?
  1070 + $countReferencesCellXf = array();
  1071 + foreach ($this->cellXfCollection as $index => $cellXf) {
  1072 + $countReferencesCellXf[$index] = 0;
  1073 + }
  1074 +
  1075 + foreach ($this->getWorksheetIterator() as $sheet) {
  1076 + // from cells
  1077 + foreach ($sheet->getCellCollection(false) as $cellID) {
  1078 + $cell = $sheet->getCell($cellID);
  1079 + ++$countReferencesCellXf[$cell->getXfIndex()];
  1080 + }
  1081 +
  1082 + // from row dimensions
  1083 + foreach ($sheet->getRowDimensions() as $rowDimension) {
  1084 + if ($rowDimension->getXfIndex() !== null) {
  1085 + ++$countReferencesCellXf[$rowDimension->getXfIndex()];
  1086 + }
  1087 + }
  1088 +
  1089 + // from column dimensions
  1090 + foreach ($sheet->getColumnDimensions() as $columnDimension) {
  1091 + ++$countReferencesCellXf[$columnDimension->getXfIndex()];
  1092 + }
  1093 + }
  1094 +
  1095 + // remove cellXfs without references and create mapping so we can update xfIndex
  1096 + // for all cells and columns
  1097 + $countNeededCellXfs = 0;
  1098 + $map = array();
  1099 + foreach ($this->cellXfCollection as $index => $cellXf) {
  1100 + if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
  1101 + ++$countNeededCellXfs;
  1102 + } else {
  1103 + unset($this->cellXfCollection[$index]);
  1104 + }
  1105 + $map[$index] = $countNeededCellXfs - 1;
  1106 + }
  1107 + $this->cellXfCollection = array_values($this->cellXfCollection);
  1108 +
  1109 + // update the index for all cellXfs
  1110 + foreach ($this->cellXfCollection as $i => $cellXf) {
  1111 + $cellXf->setIndex($i);
  1112 + }
  1113 +
  1114 + // make sure there is always at least one cellXf (there should be)
  1115 + if (empty($this->cellXfCollection)) {
  1116 + $this->cellXfCollection[] = new PHPExcel_Style();
  1117 + }
  1118 +
  1119 + // update the xfIndex for all cells, row dimensions, column dimensions
  1120 + foreach ($this->getWorksheetIterator() as $sheet) {
  1121 + // for all cells
  1122 + foreach ($sheet->getCellCollection(false) as $cellID) {
  1123 + $cell = $sheet->getCell($cellID);
  1124 + $cell->setXfIndex($map[$cell->getXfIndex()]);
  1125 + }
  1126 +
  1127 + // for all row dimensions
  1128 + foreach ($sheet->getRowDimensions() as $rowDimension) {
  1129 + if ($rowDimension->getXfIndex() !== null) {
  1130 + $rowDimension->setXfIndex($map[$rowDimension->getXfIndex()]);
  1131 + }
  1132 + }
  1133 +
  1134 + // for all column dimensions
  1135 + foreach ($sheet->getColumnDimensions() as $columnDimension) {
  1136 + $columnDimension->setXfIndex($map[$columnDimension->getXfIndex()]);
  1137 + }
  1138 +
  1139 + // also do garbage collection for all the sheets
  1140 + $sheet->garbageCollect();
  1141 + }
  1142 + }
  1143 +
  1144 + /**
  1145 + * Return the unique ID value assigned to this spreadsheet workbook
  1146 + *
  1147 + * @return string
  1148 + */
  1149 + public function getID()
  1150 + {
  1151 + return $this->uniqueID;
  1152 + }
  1153 +}
  1 +<?php
  2 +
  3 +PHPExcel_Autoloader::register();
  4 +// As we always try to run the autoloader before anything else, we can use it to do a few
  5 +// simple checks and initialisations
  6 +//PHPExcel_Shared_ZipStreamWrapper::register();
  7 +// check mbstring.func_overload
  8 +if (ini_get('mbstring.func_overload') & 2) {
  9 + throw new PHPExcel_Exception('Multibyte function overloading in PHP must be disabled for string functions (2).');
  10 +}
  11 +PHPExcel_Shared_String::buildCharacterSets();
  12 +
  13 +/**
  14 + * PHPExcel
  15 + *
  16 + * Copyright (c) 2006 - 2015 PHPExcel
  17 + *
  18 + * This library is free software; you can redistribute it and/or
  19 + * modify it under the terms of the GNU Lesser General Public
  20 + * License as published by the Free Software Foundation; either
  21 + * version 2.1 of the License, or (at your option) any later version.
  22 + *
  23 + * This library is distributed in the hope that it will be useful,
  24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  26 + * Lesser General Public License for more details.
  27 + *
  28 + * You should have received a copy of the GNU Lesser General Public
  29 + * License along with this library; if not, write to the Free Software
  30 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  31 + *
  32 + * @category PHPExcel
  33 + * @package PHPExcel
  34 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  35 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  36 + * @version ##VERSION##, ##DATE##
  37 + */
  38 +class PHPExcel_Autoloader
  39 +{
  40 + /**
  41 + * Register the Autoloader with SPL
  42 + *
  43 + */
  44 + public static function register()
  45 + {
  46 + if (function_exists('__autoload')) {
  47 + // Register any existing autoloader function with SPL, so we don't get any clashes
  48 + spl_autoload_register('__autoload');
  49 + }
  50 + // Register ourselves with SPL
  51 + if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
  52 + return spl_autoload_register(array('PHPExcel_Autoloader', 'load'), true, true);
  53 + } else {
  54 + return spl_autoload_register(array('PHPExcel_Autoloader', 'load'));
  55 + }
  56 + }
  57 +
  58 + /**
  59 + * Autoload a class identified by name
  60 + *
  61 + * @param string $pClassName Name of the object to load
  62 + */
  63 + public static function load($pClassName)
  64 + {
  65 + if ((class_exists($pClassName, false)) || (strpos($pClassName, 'PHPExcel') !== 0)) {
  66 + // Either already loaded, or not a PHPExcel class request
  67 + return false;
  68 + }
  69 +
  70 + $pClassFilePath = PHPEXCEL_ROOT .
  71 + str_replace('_', DIRECTORY_SEPARATOR, $pClassName) .
  72 + '.php';
  73 +
  74 + if ((file_exists($pClassFilePath) === false) || (is_readable($pClassFilePath) === false)) {
  75 + // Can't load
  76 + return false;
  77 + }
  78 +
  79 + require($pClassFilePath);
  80 + }
  81 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_APC
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Prefix used to uniquely identify cache data for this worksheet
  32 + *
  33 + * @access private
  34 + * @var string
  35 + */
  36 + private $cachePrefix = null;
  37 +
  38 + /**
  39 + * Cache timeout
  40 + *
  41 + * @access private
  42 + * @var integer
  43 + */
  44 + private $cacheTime = 600;
  45 +
  46 + /**
  47 + * Store cell data in cache for the current cell object if it's "dirty",
  48 + * and the 'nullify' the current cell object
  49 + *
  50 + * @access private
  51 + * @return void
  52 + * @throws PHPExcel_Exception
  53 + */
  54 + protected function storeData()
  55 + {
  56 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  57 + $this->currentObject->detach();
  58 +
  59 + if (!apc_store(
  60 + $this->cachePrefix . $this->currentObjectID . '.cache',
  61 + serialize($this->currentObject),
  62 + $this->cacheTime
  63 + )) {
  64 + $this->__destruct();
  65 + throw new PHPExcel_Exception('Failed to store cell ' . $this->currentObjectID . ' in APC');
  66 + }
  67 + $this->currentCellIsDirty = false;
  68 + }
  69 + $this->currentObjectID = $this->currentObject = null;
  70 + }
  71 +
  72 + /**
  73 + * Add or Update a cell in cache identified by coordinate address
  74 + *
  75 + * @access public
  76 + * @param string $pCoord Coordinate address of the cell to update
  77 + * @param PHPExcel_Cell $cell Cell to update
  78 + * @return PHPExcel_Cell
  79 + * @throws PHPExcel_Exception
  80 + */
  81 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  82 + {
  83 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  84 + $this->storeData();
  85 + }
  86 + $this->cellCache[$pCoord] = true;
  87 +
  88 + $this->currentObjectID = $pCoord;
  89 + $this->currentObject = $cell;
  90 + $this->currentCellIsDirty = true;
  91 +
  92 + return $cell;
  93 + }
  94 +
  95 + /**
  96 + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
  97 + *
  98 + * @access public
  99 + * @param string $pCoord Coordinate address of the cell to check
  100 + * @throws PHPExcel_Exception
  101 + * @return boolean
  102 + */
  103 + public function isDataSet($pCoord)
  104 + {
  105 + // Check if the requested entry is the current object, or exists in the cache
  106 + if (parent::isDataSet($pCoord)) {
  107 + if ($this->currentObjectID == $pCoord) {
  108 + return true;
  109 + }
  110 + // Check if the requested entry still exists in apc
  111 + $success = apc_fetch($this->cachePrefix.$pCoord.'.cache');
  112 + if ($success === false) {
  113 + // Entry no longer exists in APC, so clear it from the cache array
  114 + parent::deleteCacheData($pCoord);
  115 + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
  116 + }
  117 + return true;
  118 + }
  119 + return false;
  120 + }
  121 +
  122 + /**
  123 + * Get cell at a specific coordinate
  124 + *
  125 + * @access public
  126 + * @param string $pCoord Coordinate of the cell
  127 + * @throws PHPExcel_Exception
  128 + * @return PHPExcel_Cell Cell that was found, or null if not found
  129 + */
  130 + public function getCacheData($pCoord)
  131 + {
  132 + if ($pCoord === $this->currentObjectID) {
  133 + return $this->currentObject;
  134 + }
  135 + $this->storeData();
  136 +
  137 + // Check if the entry that has been requested actually exists
  138 + if (parent::isDataSet($pCoord)) {
  139 + $obj = apc_fetch($this->cachePrefix . $pCoord . '.cache');
  140 + if ($obj === false) {
  141 + // Entry no longer exists in APC, so clear it from the cache array
  142 + parent::deleteCacheData($pCoord);
  143 + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
  144 + }
  145 + } else {
  146 + // Return null if requested entry doesn't exist in cache
  147 + return null;
  148 + }
  149 +
  150 + // Set current entry to the requested entry
  151 + $this->currentObjectID = $pCoord;
  152 + $this->currentObject = unserialize($obj);
  153 + // Re-attach this as the cell's parent
  154 + $this->currentObject->attach($this);
  155 +
  156 + // Return requested entry
  157 + return $this->currentObject;
  158 + }
  159 +
  160 + /**
  161 + * Get a list of all cell addresses currently held in cache
  162 + *
  163 + * @return string[]
  164 + */
  165 + public function getCellList()
  166 + {
  167 + if ($this->currentObjectID !== null) {
  168 + $this->storeData();
  169 + }
  170 +
  171 + return parent::getCellList();
  172 + }
  173 +
  174 + /**
  175 + * Delete a cell in cache identified by coordinate address
  176 + *
  177 + * @access public
  178 + * @param string $pCoord Coordinate address of the cell to delete
  179 + * @throws PHPExcel_Exception
  180 + */
  181 + public function deleteCacheData($pCoord)
  182 + {
  183 + // Delete the entry from APC
  184 + apc_delete($this->cachePrefix.$pCoord.'.cache');
  185 +
  186 + // Delete the entry from our cell address array
  187 + parent::deleteCacheData($pCoord);
  188 + }
  189 +
  190 + /**
  191 + * Clone the cell collection
  192 + *
  193 + * @access public
  194 + * @param PHPExcel_Worksheet $parent The new worksheet
  195 + * @throws PHPExcel_Exception
  196 + * @return void
  197 + */
  198 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  199 + {
  200 + parent::copyCellCollection($parent);
  201 + // Get a new id for the new file name
  202 + $baseUnique = $this->getUniqueID();
  203 + $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.';
  204 + $cacheList = $this->getCellList();
  205 + foreach ($cacheList as $cellID) {
  206 + if ($cellID != $this->currentObjectID) {
  207 + $obj = apc_fetch($this->cachePrefix . $cellID . '.cache');
  208 + if ($obj === false) {
  209 + // Entry no longer exists in APC, so clear it from the cache array
  210 + parent::deleteCacheData($cellID);
  211 + throw new PHPExcel_Exception('Cell entry ' . $cellID . ' no longer exists in APC');
  212 + }
  213 + if (!apc_store($newCachePrefix . $cellID . '.cache', $obj, $this->cacheTime)) {
  214 + $this->__destruct();
  215 + throw new PHPExcel_Exception('Failed to store cell ' . $cellID . ' in APC');
  216 + }
  217 + }
  218 + }
  219 + $this->cachePrefix = $newCachePrefix;
  220 + }
  221 +
  222 + /**
  223 + * Clear the cell collection and disconnect from our parent
  224 + *
  225 + * @return void
  226 + */
  227 + public function unsetWorksheetCells()
  228 + {
  229 + if ($this->currentObject !== null) {
  230 + $this->currentObject->detach();
  231 + $this->currentObject = $this->currentObjectID = null;
  232 + }
  233 +
  234 + // Flush the APC cache
  235 + $this->__destruct();
  236 +
  237 + $this->cellCache = array();
  238 +
  239 + // detach ourself from the worksheet, so that it can then delete this object successfully
  240 + $this->parent = null;
  241 + }
  242 +
  243 + /**
  244 + * Initialise this new cell collection
  245 + *
  246 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  247 + * @param array of mixed $arguments Additional initialisation arguments
  248 + */
  249 + public function __construct(PHPExcel_Worksheet $parent, $arguments)
  250 + {
  251 + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600;
  252 +
  253 + if ($this->cachePrefix === null) {
  254 + $baseUnique = $this->getUniqueID();
  255 + $this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.';
  256 + $this->cacheTime = $cacheTime;
  257 +
  258 + parent::__construct($parent);
  259 + }
  260 + }
  261 +
  262 + /**
  263 + * Destroy this cell collection
  264 + */
  265 + public function __destruct()
  266 + {
  267 + $cacheList = $this->getCellList();
  268 + foreach ($cacheList as $cellID) {
  269 + apc_delete($this->cachePrefix . $cellID . '.cache');
  270 + }
  271 + }
  272 +
  273 + /**
  274 + * Identify whether the caching method is currently available
  275 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  276 + *
  277 + * @return boolean
  278 + */
  279 + public static function cacheMethodIsAvailable()
  280 + {
  281 + if (!function_exists('apc_store')) {
  282 + return false;
  283 + }
  284 + if (apc_sma_info() === false) {
  285 + return false;
  286 + }
  287 +
  288 + return true;
  289 + }
  290 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_CacheBase
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +abstract class PHPExcel_CachedObjectStorage_CacheBase
  29 +{
  30 + /**
  31 + * Parent worksheet
  32 + *
  33 + * @var PHPExcel_Worksheet
  34 + */
  35 + protected $parent;
  36 +
  37 + /**
  38 + * The currently active Cell
  39 + *
  40 + * @var PHPExcel_Cell
  41 + */
  42 + protected $currentObject = null;
  43 +
  44 + /**
  45 + * Coordinate address of the currently active Cell
  46 + *
  47 + * @var string
  48 + */
  49 + protected $currentObjectID = null;
  50 +
  51 + /**
  52 + * Flag indicating whether the currently active Cell requires saving
  53 + *
  54 + * @var boolean
  55 + */
  56 + protected $currentCellIsDirty = true;
  57 +
  58 + /**
  59 + * An array of cells or cell pointers for the worksheet cells held in this cache,
  60 + * and indexed by their coordinate address within the worksheet
  61 + *
  62 + * @var array of mixed
  63 + */
  64 + protected $cellCache = array();
  65 +
  66 + /**
  67 + * Initialise this new cell collection
  68 + *
  69 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  70 + */
  71 + public function __construct(PHPExcel_Worksheet $parent)
  72 + {
  73 + // Set our parent worksheet.
  74 + // This is maintained within the cache controller to facilitate re-attaching it to PHPExcel_Cell objects when
  75 + // they are woken from a serialized state
  76 + $this->parent = $parent;
  77 + }
  78 +
  79 + /**
  80 + * Return the parent worksheet for this cell collection
  81 + *
  82 + * @return PHPExcel_Worksheet
  83 + */
  84 + public function getParent()
  85 + {
  86 + return $this->parent;
  87 + }
  88 +
  89 + /**
  90 + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
  91 + *
  92 + * @param string $pCoord Coordinate address of the cell to check
  93 + * @return boolean
  94 + */
  95 + public function isDataSet($pCoord)
  96 + {
  97 + if ($pCoord === $this->currentObjectID) {
  98 + return true;
  99 + }
  100 + // Check if the requested entry exists in the cache
  101 + return isset($this->cellCache[$pCoord]);
  102 + }
  103 +
  104 + /**
  105 + * Move a cell object from one address to another
  106 + *
  107 + * @param string $fromAddress Current address of the cell to move
  108 + * @param string $toAddress Destination address of the cell to move
  109 + * @return boolean
  110 + */
  111 + public function moveCell($fromAddress, $toAddress)
  112 + {
  113 + if ($fromAddress === $this->currentObjectID) {
  114 + $this->currentObjectID = $toAddress;
  115 + }
  116 + $this->currentCellIsDirty = true;
  117 + if (isset($this->cellCache[$fromAddress])) {
  118 + $this->cellCache[$toAddress] = &$this->cellCache[$fromAddress];
  119 + unset($this->cellCache[$fromAddress]);
  120 + }
  121 +
  122 + return true;
  123 + }
  124 +
  125 + /**
  126 + * Add or Update a cell in cache
  127 + *
  128 + * @param PHPExcel_Cell $cell Cell to update
  129 + * @return PHPExcel_Cell
  130 + * @throws PHPExcel_Exception
  131 + */
  132 + public function updateCacheData(PHPExcel_Cell $cell)
  133 + {
  134 + return $this->addCacheData($cell->getCoordinate(), $cell);
  135 + }
  136 +
  137 + /**
  138 + * Delete a cell in cache identified by coordinate address
  139 + *
  140 + * @param string $pCoord Coordinate address of the cell to delete
  141 + * @throws PHPExcel_Exception
  142 + */
  143 + public function deleteCacheData($pCoord)
  144 + {
  145 + if ($pCoord === $this->currentObjectID && !is_null($this->currentObject)) {
  146 + $this->currentObject->detach();
  147 + $this->currentObjectID = $this->currentObject = null;
  148 + }
  149 +
  150 + if (is_object($this->cellCache[$pCoord])) {
  151 + $this->cellCache[$pCoord]->detach();
  152 + unset($this->cellCache[$pCoord]);
  153 + }
  154 + $this->currentCellIsDirty = false;
  155 + }
  156 +
  157 + /**
  158 + * Get a list of all cell addresses currently held in cache
  159 + *
  160 + * @return string[]
  161 + */
  162 + public function getCellList()
  163 + {
  164 + return array_keys($this->cellCache);
  165 + }
  166 +
  167 + /**
  168 + * Sort the list of all cell addresses currently held in cache by row and column
  169 + *
  170 + * @return string[]
  171 + */
  172 + public function getSortedCellList()
  173 + {
  174 + $sortKeys = array();
  175 + foreach ($this->getCellList() as $coord) {
  176 + sscanf($coord, '%[A-Z]%d', $column, $row);
  177 + $sortKeys[sprintf('%09d%3s', $row, $column)] = $coord;
  178 + }
  179 + ksort($sortKeys);
  180 +
  181 + return array_values($sortKeys);
  182 + }
  183 +
  184 + /**
  185 + * Get highest worksheet column and highest row that have cell records
  186 + *
  187 + * @return array Highest column name and highest row number
  188 + */
  189 + public function getHighestRowAndColumn()
  190 + {
  191 + // Lookup highest column and highest row
  192 + $col = array('A' => '1A');
  193 + $row = array(1);
  194 + foreach ($this->getCellList() as $coord) {
  195 + sscanf($coord, '%[A-Z]%d', $c, $r);
  196 + $row[$r] = $r;
  197 + $col[$c] = strlen($c).$c;
  198 + }
  199 + if (!empty($row)) {
  200 + // Determine highest column and row
  201 + $highestRow = max($row);
  202 + $highestColumn = substr(max($col), 1);
  203 + }
  204 +
  205 + return array(
  206 + 'row' => $highestRow,
  207 + 'column' => $highestColumn
  208 + );
  209 + }
  210 +
  211 + /**
  212 + * Return the cell address of the currently active cell object
  213 + *
  214 + * @return string
  215 + */
  216 + public function getCurrentAddress()
  217 + {
  218 + return $this->currentObjectID;
  219 + }
  220 +
  221 + /**
  222 + * Return the column address of the currently active cell object
  223 + *
  224 + * @return string
  225 + */
  226 + public function getCurrentColumn()
  227 + {
  228 + sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row);
  229 + return $column;
  230 + }
  231 +
  232 + /**
  233 + * Return the row address of the currently active cell object
  234 + *
  235 + * @return integer
  236 + */
  237 + public function getCurrentRow()
  238 + {
  239 + sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row);
  240 + return (integer) $row;
  241 + }
  242 +
  243 + /**
  244 + * Get highest worksheet column
  245 + *
  246 + * @param string $row Return the highest column for the specified row,
  247 + * or the highest column of any row if no row number is passed
  248 + * @return string Highest column name
  249 + */
  250 + public function getHighestColumn($row = null)
  251 + {
  252 + if ($row == null) {
  253 + $colRow = $this->getHighestRowAndColumn();
  254 + return $colRow['column'];
  255 + }
  256 +
  257 + $columnList = array(1);
  258 + foreach ($this->getCellList() as $coord) {
  259 + sscanf($coord, '%[A-Z]%d', $c, $r);
  260 + if ($r != $row) {
  261 + continue;
  262 + }
  263 + $columnList[] = PHPExcel_Cell::columnIndexFromString($c);
  264 + }
  265 + return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1);
  266 + }
  267 +
  268 + /**
  269 + * Get highest worksheet row
  270 + *
  271 + * @param string $column Return the highest row for the specified column,
  272 + * or the highest row of any column if no column letter is passed
  273 + * @return int Highest row number
  274 + */
  275 + public function getHighestRow($column = null)
  276 + {
  277 + if ($column == null) {
  278 + $colRow = $this->getHighestRowAndColumn();
  279 + return $colRow['row'];
  280 + }
  281 +
  282 + $rowList = array(0);
  283 + foreach ($this->getCellList() as $coord) {
  284 + sscanf($coord, '%[A-Z]%d', $c, $r);
  285 + if ($c != $column) {
  286 + continue;
  287 + }
  288 + $rowList[] = $r;
  289 + }
  290 +
  291 + return max($rowList);
  292 + }
  293 +
  294 + /**
  295 + * Generate a unique ID for cache referencing
  296 + *
  297 + * @return string Unique Reference
  298 + */
  299 + protected function getUniqueID()
  300 + {
  301 + if (function_exists('posix_getpid')) {
  302 + $baseUnique = posix_getpid();
  303 + } else {
  304 + $baseUnique = mt_rand();
  305 + }
  306 + return uniqid($baseUnique, true);
  307 + }
  308 +
  309 + /**
  310 + * Clone the cell collection
  311 + *
  312 + * @param PHPExcel_Worksheet $parent The new worksheet
  313 + * @return void
  314 + */
  315 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  316 + {
  317 + $this->currentCellIsDirty;
  318 + $this->storeData();
  319 +
  320 + $this->parent = $parent;
  321 + if (($this->currentObject !== null) && (is_object($this->currentObject))) {
  322 + $this->currentObject->attach($this);
  323 + }
  324 + } // function copyCellCollection()
  325 +
  326 + /**
  327 + * Remove a row, deleting all cells in that row
  328 + *
  329 + * @param string $row Row number to remove
  330 + * @return void
  331 + */
  332 + public function removeRow($row)
  333 + {
  334 + foreach ($this->getCellList() as $coord) {
  335 + sscanf($coord, '%[A-Z]%d', $c, $r);
  336 + if ($r == $row) {
  337 + $this->deleteCacheData($coord);
  338 + }
  339 + }
  340 + }
  341 +
  342 + /**
  343 + * Remove a column, deleting all cells in that column
  344 + *
  345 + * @param string $column Column ID to remove
  346 + * @return void
  347 + */
  348 + public function removeColumn($column)
  349 + {
  350 + foreach ($this->getCellList() as $coord) {
  351 + sscanf($coord, '%[A-Z]%d', $c, $r);
  352 + if ($c == $column) {
  353 + $this->deleteCacheData($coord);
  354 + }
  355 + }
  356 + }
  357 +
  358 + /**
  359 + * Identify whether the caching method is currently available
  360 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  361 + *
  362 + * @return boolean
  363 + */
  364 + public static function cacheMethodIsAvailable()
  365 + {
  366 + return true;
  367 + }
  368 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_DiscISAM
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Name of the file for this cache
  32 + *
  33 + * @var string
  34 + */
  35 + private $fileName = null;
  36 +
  37 + /**
  38 + * File handle for this cache file
  39 + *
  40 + * @var resource
  41 + */
  42 + private $fileHandle = null;
  43 +
  44 + /**
  45 + * Directory/Folder where the cache file is located
  46 + *
  47 + * @var string
  48 + */
  49 + private $cacheDirectory = null;
  50 +
  51 + /**
  52 + * Store cell data in cache for the current cell object if it's "dirty",
  53 + * and the 'nullify' the current cell object
  54 + *
  55 + * @return void
  56 + * @throws PHPExcel_Exception
  57 + */
  58 + protected function storeData()
  59 + {
  60 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  61 + $this->currentObject->detach();
  62 +
  63 + fseek($this->fileHandle, 0, SEEK_END);
  64 +
  65 + $this->cellCache[$this->currentObjectID] = array(
  66 + 'ptr' => ftell($this->fileHandle),
  67 + 'sz' => fwrite($this->fileHandle, serialize($this->currentObject))
  68 + );
  69 + $this->currentCellIsDirty = false;
  70 + }
  71 + $this->currentObjectID = $this->currentObject = null;
  72 + }
  73 +
  74 + /**
  75 + * Add or Update a cell in cache identified by coordinate address
  76 + *
  77 + * @param string $pCoord Coordinate address of the cell to update
  78 + * @param PHPExcel_Cell $cell Cell to update
  79 + * @return PHPExcel_Cell
  80 + * @throws PHPExcel_Exception
  81 + */
  82 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  83 + {
  84 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  85 + $this->storeData();
  86 + }
  87 +
  88 + $this->currentObjectID = $pCoord;
  89 + $this->currentObject = $cell;
  90 + $this->currentCellIsDirty = true;
  91 +
  92 + return $cell;
  93 + }
  94 +
  95 + /**
  96 + * Get cell at a specific coordinate
  97 + *
  98 + * @param string $pCoord Coordinate of the cell
  99 + * @throws PHPExcel_Exception
  100 + * @return PHPExcel_Cell Cell that was found, or null if not found
  101 + */
  102 + public function getCacheData($pCoord)
  103 + {
  104 + if ($pCoord === $this->currentObjectID) {
  105 + return $this->currentObject;
  106 + }
  107 + $this->storeData();
  108 +
  109 + // Check if the entry that has been requested actually exists
  110 + if (!isset($this->cellCache[$pCoord])) {
  111 + // Return null if requested entry doesn't exist in cache
  112 + return null;
  113 + }
  114 +
  115 + // Set current entry to the requested entry
  116 + $this->currentObjectID = $pCoord;
  117 + fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']);
  118 + $this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz']));
  119 + // Re-attach this as the cell's parent
  120 + $this->currentObject->attach($this);
  121 +
  122 + // Return requested entry
  123 + return $this->currentObject;
  124 + }
  125 +
  126 + /**
  127 + * Get a list of all cell addresses currently held in cache
  128 + *
  129 + * @return string[]
  130 + */
  131 + public function getCellList()
  132 + {
  133 + if ($this->currentObjectID !== null) {
  134 + $this->storeData();
  135 + }
  136 +
  137 + return parent::getCellList();
  138 + }
  139 +
  140 + /**
  141 + * Clone the cell collection
  142 + *
  143 + * @param PHPExcel_Worksheet $parent The new worksheet
  144 + */
  145 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  146 + {
  147 + parent::copyCellCollection($parent);
  148 + // Get a new id for the new file name
  149 + $baseUnique = $this->getUniqueID();
  150 + $newFileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';
  151 + // Copy the existing cell cache file
  152 + copy($this->fileName, $newFileName);
  153 + $this->fileName = $newFileName;
  154 + // Open the copied cell cache file
  155 + $this->fileHandle = fopen($this->fileName, 'a+');
  156 + }
  157 +
  158 + /**
  159 + * Clear the cell collection and disconnect from our parent
  160 + *
  161 + */
  162 + public function unsetWorksheetCells()
  163 + {
  164 + if (!is_null($this->currentObject)) {
  165 + $this->currentObject->detach();
  166 + $this->currentObject = $this->currentObjectID = null;
  167 + }
  168 + $this->cellCache = array();
  169 +
  170 + // detach ourself from the worksheet, so that it can then delete this object successfully
  171 + $this->parent = null;
  172 +
  173 + // Close down the temporary cache file
  174 + $this->__destruct();
  175 + }
  176 +
  177 + /**
  178 + * Initialise this new cell collection
  179 + *
  180 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  181 + * @param array of mixed $arguments Additional initialisation arguments
  182 + */
  183 + public function __construct(PHPExcel_Worksheet $parent, $arguments)
  184 + {
  185 + $this->cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== null))
  186 + ? $arguments['dir']
  187 + : PHPExcel_Shared_File::sys_get_temp_dir();
  188 +
  189 + parent::__construct($parent);
  190 + if (is_null($this->fileHandle)) {
  191 + $baseUnique = $this->getUniqueID();
  192 + $this->fileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';
  193 + $this->fileHandle = fopen($this->fileName, 'a+');
  194 + }
  195 + }
  196 +
  197 + /**
  198 + * Destroy this cell collection
  199 + */
  200 + public function __destruct()
  201 + {
  202 + if (!is_null($this->fileHandle)) {
  203 + fclose($this->fileHandle);
  204 + unlink($this->fileName);
  205 + }
  206 + $this->fileHandle = null;
  207 + }
  208 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_ICache
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +interface PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Add or Update a cell in cache identified by coordinate address
  32 + *
  33 + * @param string $pCoord Coordinate address of the cell to update
  34 + * @param PHPExcel_Cell $cell Cell to update
  35 + * @return PHPExcel_Cell
  36 + * @throws PHPExcel_Exception
  37 + */
  38 + public function addCacheData($pCoord, PHPExcel_Cell $cell);
  39 +
  40 + /**
  41 + * Add or Update a cell in cache
  42 + *
  43 + * @param PHPExcel_Cell $cell Cell to update
  44 + * @return PHPExcel_Cell
  45 + * @throws PHPExcel_Exception
  46 + */
  47 + public function updateCacheData(PHPExcel_Cell $cell);
  48 +
  49 + /**
  50 + * Fetch a cell from cache identified by coordinate address
  51 + *
  52 + * @param string $pCoord Coordinate address of the cell to retrieve
  53 + * @return PHPExcel_Cell Cell that was found, or null if not found
  54 + * @throws PHPExcel_Exception
  55 + */
  56 + public function getCacheData($pCoord);
  57 +
  58 + /**
  59 + * Delete a cell in cache identified by coordinate address
  60 + *
  61 + * @param string $pCoord Coordinate address of the cell to delete
  62 + * @throws PHPExcel_Exception
  63 + */
  64 + public function deleteCacheData($pCoord);
  65 +
  66 + /**
  67 + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
  68 + *
  69 + * @param string $pCoord Coordinate address of the cell to check
  70 + * @return boolean
  71 + */
  72 + public function isDataSet($pCoord);
  73 +
  74 + /**
  75 + * Get a list of all cell addresses currently held in cache
  76 + *
  77 + * @return string[]
  78 + */
  79 + public function getCellList();
  80 +
  81 + /**
  82 + * Get the list of all cell addresses currently held in cache sorted by column and row
  83 + *
  84 + * @return string[]
  85 + */
  86 + public function getSortedCellList();
  87 +
  88 + /**
  89 + * Clone the cell collection
  90 + *
  91 + * @param PHPExcel_Worksheet $parent The new worksheet
  92 + * @return void
  93 + */
  94 + public function copyCellCollection(PHPExcel_Worksheet $parent);
  95 +
  96 + /**
  97 + * Identify whether the caching method is currently available
  98 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  99 + *
  100 + * @return boolean
  101 + */
  102 + public static function cacheMethodIsAvailable();
  103 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_Igbinary
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Store cell data in cache for the current cell object if it's "dirty",
  32 + * and the 'nullify' the current cell object
  33 + *
  34 + * @return void
  35 + * @throws PHPExcel_Exception
  36 + */
  37 + protected function storeData()
  38 + {
  39 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  40 + $this->currentObject->detach();
  41 +
  42 + $this->cellCache[$this->currentObjectID] = igbinary_serialize($this->currentObject);
  43 + $this->currentCellIsDirty = false;
  44 + }
  45 + $this->currentObjectID = $this->currentObject = null;
  46 + } // function _storeData()
  47 +
  48 +
  49 + /**
  50 + * Add or Update a cell in cache identified by coordinate address
  51 + *
  52 + * @param string $pCoord Coordinate address of the cell to update
  53 + * @param PHPExcel_Cell $cell Cell to update
  54 + * @return PHPExcel_Cell
  55 + * @throws PHPExcel_Exception
  56 + */
  57 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  58 + {
  59 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  60 + $this->storeData();
  61 + }
  62 +
  63 + $this->currentObjectID = $pCoord;
  64 + $this->currentObject = $cell;
  65 + $this->currentCellIsDirty = true;
  66 +
  67 + return $cell;
  68 + } // function addCacheData()
  69 +
  70 +
  71 + /**
  72 + * Get cell at a specific coordinate
  73 + *
  74 + * @param string $pCoord Coordinate of the cell
  75 + * @throws PHPExcel_Exception
  76 + * @return PHPExcel_Cell Cell that was found, or null if not found
  77 + */
  78 + public function getCacheData($pCoord)
  79 + {
  80 + if ($pCoord === $this->currentObjectID) {
  81 + return $this->currentObject;
  82 + }
  83 + $this->storeData();
  84 +
  85 + // Check if the entry that has been requested actually exists
  86 + if (!isset($this->cellCache[$pCoord])) {
  87 + // Return null if requested entry doesn't exist in cache
  88 + return null;
  89 + }
  90 +
  91 + // Set current entry to the requested entry
  92 + $this->currentObjectID = $pCoord;
  93 + $this->currentObject = igbinary_unserialize($this->cellCache[$pCoord]);
  94 + // Re-attach this as the cell's parent
  95 + $this->currentObject->attach($this);
  96 +
  97 + // Return requested entry
  98 + return $this->currentObject;
  99 + } // function getCacheData()
  100 +
  101 +
  102 + /**
  103 + * Get a list of all cell addresses currently held in cache
  104 + *
  105 + * @return string[]
  106 + */
  107 + public function getCellList()
  108 + {
  109 + if ($this->currentObjectID !== null) {
  110 + $this->storeData();
  111 + }
  112 +
  113 + return parent::getCellList();
  114 + }
  115 +
  116 +
  117 + /**
  118 + * Clear the cell collection and disconnect from our parent
  119 + *
  120 + * @return void
  121 + */
  122 + public function unsetWorksheetCells()
  123 + {
  124 + if (!is_null($this->currentObject)) {
  125 + $this->currentObject->detach();
  126 + $this->currentObject = $this->currentObjectID = null;
  127 + }
  128 + $this->cellCache = array();
  129 +
  130 + // detach ourself from the worksheet, so that it can then delete this object successfully
  131 + $this->parent = null;
  132 + } // function unsetWorksheetCells()
  133 +
  134 +
  135 + /**
  136 + * Identify whether the caching method is currently available
  137 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  138 + *
  139 + * @return boolean
  140 + */
  141 + public static function cacheMethodIsAvailable()
  142 + {
  143 + if (!function_exists('igbinary_serialize')) {
  144 + return false;
  145 + }
  146 +
  147 + return true;
  148 + }
  149 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_Memcache
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Prefix used to uniquely identify cache data for this worksheet
  32 + *
  33 + * @var string
  34 + */
  35 + private $cachePrefix = null;
  36 +
  37 + /**
  38 + * Cache timeout
  39 + *
  40 + * @var integer
  41 + */
  42 + private $cacheTime = 600;
  43 +
  44 + /**
  45 + * Memcache interface
  46 + *
  47 + * @var resource
  48 + */
  49 + private $memcache = null;
  50 +
  51 +
  52 + /**
  53 + * Store cell data in cache for the current cell object if it's "dirty",
  54 + * and the 'nullify' the current cell object
  55 + *
  56 + * @return void
  57 + * @throws PHPExcel_Exception
  58 + */
  59 + protected function storeData()
  60 + {
  61 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  62 + $this->currentObject->detach();
  63 +
  64 + $obj = serialize($this->currentObject);
  65 + if (!$this->memcache->replace($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) {
  66 + if (!$this->memcache->add($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) {
  67 + $this->__destruct();
  68 + throw new PHPExcel_Exception("Failed to store cell {$this->currentObjectID} in MemCache");
  69 + }
  70 + }
  71 + $this->currentCellIsDirty = false;
  72 + }
  73 + $this->currentObjectID = $this->currentObject = null;
  74 + } // function _storeData()
  75 +
  76 +
  77 + /**
  78 + * Add or Update a cell in cache identified by coordinate address
  79 + *
  80 + * @param string $pCoord Coordinate address of the cell to update
  81 + * @param PHPExcel_Cell $cell Cell to update
  82 + * @return PHPExcel_Cell
  83 + * @throws PHPExcel_Exception
  84 + */
  85 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  86 + {
  87 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  88 + $this->storeData();
  89 + }
  90 + $this->cellCache[$pCoord] = true;
  91 +
  92 + $this->currentObjectID = $pCoord;
  93 + $this->currentObject = $cell;
  94 + $this->currentCellIsDirty = true;
  95 +
  96 + return $cell;
  97 + } // function addCacheData()
  98 +
  99 +
  100 + /**
  101 + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
  102 + *
  103 + * @param string $pCoord Coordinate address of the cell to check
  104 + * @return boolean
  105 + * @return boolean
  106 + */
  107 + public function isDataSet($pCoord)
  108 + {
  109 + // Check if the requested entry is the current object, or exists in the cache
  110 + if (parent::isDataSet($pCoord)) {
  111 + if ($this->currentObjectID == $pCoord) {
  112 + return true;
  113 + }
  114 + // Check if the requested entry still exists in Memcache
  115 + $success = $this->memcache->get($this->cachePrefix.$pCoord.'.cache');
  116 + if ($success === false) {
  117 + // Entry no longer exists in Memcache, so clear it from the cache array
  118 + parent::deleteCacheData($pCoord);
  119 + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');
  120 + }
  121 + return true;
  122 + }
  123 + return false;
  124 + }
  125 +
  126 +
  127 + /**
  128 + * Get cell at a specific coordinate
  129 + *
  130 + * @param string $pCoord Coordinate of the cell
  131 + * @throws PHPExcel_Exception
  132 + * @return PHPExcel_Cell Cell that was found, or null if not found
  133 + */
  134 + public function getCacheData($pCoord)
  135 + {
  136 + if ($pCoord === $this->currentObjectID) {
  137 + return $this->currentObject;
  138 + }
  139 + $this->storeData();
  140 +
  141 + // Check if the entry that has been requested actually exists
  142 + if (parent::isDataSet($pCoord)) {
  143 + $obj = $this->memcache->get($this->cachePrefix . $pCoord . '.cache');
  144 + if ($obj === false) {
  145 + // Entry no longer exists in Memcache, so clear it from the cache array
  146 + parent::deleteCacheData($pCoord);
  147 + throw new PHPExcel_Exception("Cell entry {$pCoord} no longer exists in MemCache");
  148 + }
  149 + } else {
  150 + // Return null if requested entry doesn't exist in cache
  151 + return null;
  152 + }
  153 +
  154 + // Set current entry to the requested entry
  155 + $this->currentObjectID = $pCoord;
  156 + $this->currentObject = unserialize($obj);
  157 + // Re-attach this as the cell's parent
  158 + $this->currentObject->attach($this);
  159 +
  160 + // Return requested entry
  161 + return $this->currentObject;
  162 + }
  163 +
  164 + /**
  165 + * Get a list of all cell addresses currently held in cache
  166 + *
  167 + * @return string[]
  168 + */
  169 + public function getCellList()
  170 + {
  171 + if ($this->currentObjectID !== null) {
  172 + $this->storeData();
  173 + }
  174 +
  175 + return parent::getCellList();
  176 + }
  177 +
  178 + /**
  179 + * Delete a cell in cache identified by coordinate address
  180 + *
  181 + * @param string $pCoord Coordinate address of the cell to delete
  182 + * @throws PHPExcel_Exception
  183 + */
  184 + public function deleteCacheData($pCoord)
  185 + {
  186 + // Delete the entry from Memcache
  187 + $this->memcache->delete($this->cachePrefix . $pCoord . '.cache');
  188 +
  189 + // Delete the entry from our cell address array
  190 + parent::deleteCacheData($pCoord);
  191 + }
  192 +
  193 + /**
  194 + * Clone the cell collection
  195 + *
  196 + * @param PHPExcel_Worksheet $parent The new worksheet
  197 + * @return void
  198 + */
  199 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  200 + {
  201 + parent::copyCellCollection($parent);
  202 + // Get a new id for the new file name
  203 + $baseUnique = $this->getUniqueID();
  204 + $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.';
  205 + $cacheList = $this->getCellList();
  206 + foreach ($cacheList as $cellID) {
  207 + if ($cellID != $this->currentObjectID) {
  208 + $obj = $this->memcache->get($this->cachePrefix.$cellID.'.cache');
  209 + if ($obj === false) {
  210 + // Entry no longer exists in Memcache, so clear it from the cache array
  211 + parent::deleteCacheData($cellID);
  212 + throw new PHPExcel_Exception("Cell entry {$cellID} no longer exists in MemCache");
  213 + }
  214 + if (!$this->memcache->add($newCachePrefix . $cellID . '.cache', $obj, null, $this->cacheTime)) {
  215 + $this->__destruct();
  216 + throw new PHPExcel_Exception("Failed to store cell {$cellID} in MemCache");
  217 + }
  218 + }
  219 + }
  220 + $this->cachePrefix = $newCachePrefix;
  221 + }
  222 +
  223 + /**
  224 + * Clear the cell collection and disconnect from our parent
  225 + *
  226 + * @return void
  227 + */
  228 + public function unsetWorksheetCells()
  229 + {
  230 + if (!is_null($this->currentObject)) {
  231 + $this->currentObject->detach();
  232 + $this->currentObject = $this->currentObjectID = null;
  233 + }
  234 +
  235 + // Flush the Memcache cache
  236 + $this->__destruct();
  237 +
  238 + $this->cellCache = array();
  239 +
  240 + // detach ourself from the worksheet, so that it can then delete this object successfully
  241 + $this->parent = null;
  242 + }
  243 +
  244 + /**
  245 + * Initialise this new cell collection
  246 + *
  247 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  248 + * @param array of mixed $arguments Additional initialisation arguments
  249 + */
  250 + public function __construct(PHPExcel_Worksheet $parent, $arguments)
  251 + {
  252 + $memcacheServer = (isset($arguments['memcacheServer'])) ? $arguments['memcacheServer'] : 'localhost';
  253 + $memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211;
  254 + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600;
  255 +
  256 + if (is_null($this->cachePrefix)) {
  257 + $baseUnique = $this->getUniqueID();
  258 + $this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.';
  259 +
  260 + // Set a new Memcache object and connect to the Memcache server
  261 + $this->memcache = new Memcache();
  262 + if (!$this->memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) {
  263 + throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}");
  264 + }
  265 + $this->cacheTime = $cacheTime;
  266 +
  267 + parent::__construct($parent);
  268 + }
  269 + }
  270 +
  271 + /**
  272 + * Memcache error handler
  273 + *
  274 + * @param string $host Memcache server
  275 + * @param integer $port Memcache port
  276 + * @throws PHPExcel_Exception
  277 + */
  278 + public function failureCallback($host, $port)
  279 + {
  280 + throw new PHPExcel_Exception("memcache {$host}:{$port} failed");
  281 + }
  282 +
  283 + /**
  284 + * Destroy this cell collection
  285 + */
  286 + public function __destruct()
  287 + {
  288 + $cacheList = $this->getCellList();
  289 + foreach ($cacheList as $cellID) {
  290 + $this->memcache->delete($this->cachePrefix.$cellID . '.cache');
  291 + }
  292 + }
  293 +
  294 + /**
  295 + * Identify whether the caching method is currently available
  296 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  297 + *
  298 + * @return boolean
  299 + */
  300 + public static function cacheMethodIsAvailable()
  301 + {
  302 + if (!function_exists('memcache_add')) {
  303 + return false;
  304 + }
  305 +
  306 + return true;
  307 + }
  308 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_Memory
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Dummy method callable from CacheBase, but unused by Memory cache
  32 + *
  33 + * @return void
  34 + */
  35 + protected function storeData()
  36 + {
  37 + }
  38 +
  39 + /**
  40 + * Add or Update a cell in cache identified by coordinate address
  41 + *
  42 + * @param string $pCoord Coordinate address of the cell to update
  43 + * @param PHPExcel_Cell $cell Cell to update
  44 + * @return PHPExcel_Cell
  45 + * @throws PHPExcel_Exception
  46 + */
  47 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  48 + {
  49 + $this->cellCache[$pCoord] = $cell;
  50 +
  51 + // Set current entry to the new/updated entry
  52 + $this->currentObjectID = $pCoord;
  53 +
  54 + return $cell;
  55 + }
  56 +
  57 +
  58 + /**
  59 + * Get cell at a specific coordinate
  60 + *
  61 + * @param string $pCoord Coordinate of the cell
  62 + * @throws PHPExcel_Exception
  63 + * @return PHPExcel_Cell Cell that was found, or null if not found
  64 + */
  65 + public function getCacheData($pCoord)
  66 + {
  67 + // Check if the entry that has been requested actually exists
  68 + if (!isset($this->cellCache[$pCoord])) {
  69 + $this->currentObjectID = null;
  70 + // Return null if requested entry doesn't exist in cache
  71 + return null;
  72 + }
  73 +
  74 + // Set current entry to the requested entry
  75 + $this->currentObjectID = $pCoord;
  76 +
  77 + // Return requested entry
  78 + return $this->cellCache[$pCoord];
  79 + }
  80 +
  81 +
  82 + /**
  83 + * Clone the cell collection
  84 + *
  85 + * @param PHPExcel_Worksheet $parent The new worksheet
  86 + */
  87 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  88 + {
  89 + parent::copyCellCollection($parent);
  90 +
  91 + $newCollection = array();
  92 + foreach ($this->cellCache as $k => &$cell) {
  93 + $newCollection[$k] = clone $cell;
  94 + $newCollection[$k]->attach($this);
  95 + }
  96 +
  97 + $this->cellCache = $newCollection;
  98 + }
  99 +
  100 + /**
  101 + * Clear the cell collection and disconnect from our parent
  102 + *
  103 + */
  104 + public function unsetWorksheetCells()
  105 + {
  106 + // Because cells are all stored as intact objects in memory, we need to detach each one from the parent
  107 + foreach ($this->cellCache as $k => &$cell) {
  108 + $cell->detach();
  109 + $this->cellCache[$k] = null;
  110 + }
  111 + unset($cell);
  112 +
  113 + $this->cellCache = array();
  114 +
  115 + // detach ourself from the worksheet, so that it can then delete this object successfully
  116 + $this->parent = null;
  117 + }
  118 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_MemoryGZip
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Store cell data in cache for the current cell object if it's "dirty",
  32 + * and the 'nullify' the current cell object
  33 + *
  34 + * @return void
  35 + * @throws PHPExcel_Exception
  36 + */
  37 + protected function storeData()
  38 + {
  39 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  40 + $this->currentObject->detach();
  41 +
  42 + $this->cellCache[$this->currentObjectID] = gzdeflate(serialize($this->currentObject));
  43 + $this->currentCellIsDirty = false;
  44 + }
  45 + $this->currentObjectID = $this->currentObject = null;
  46 + }
  47 +
  48 +
  49 + /**
  50 + * Add or Update a cell in cache identified by coordinate address
  51 + *
  52 + * @param string $pCoord Coordinate address of the cell to update
  53 + * @param PHPExcel_Cell $cell Cell to update
  54 + * @return PHPExcel_Cell
  55 + * @throws PHPExcel_Exception
  56 + */
  57 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  58 + {
  59 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  60 + $this->storeData();
  61 + }
  62 +
  63 + $this->currentObjectID = $pCoord;
  64 + $this->currentObject = $cell;
  65 + $this->currentCellIsDirty = true;
  66 +
  67 + return $cell;
  68 + }
  69 +
  70 +
  71 + /**
  72 + * Get cell at a specific coordinate
  73 + *
  74 + * @param string $pCoord Coordinate of the cell
  75 + * @throws PHPExcel_Exception
  76 + * @return PHPExcel_Cell Cell that was found, or null if not found
  77 + */
  78 + public function getCacheData($pCoord)
  79 + {
  80 + if ($pCoord === $this->currentObjectID) {
  81 + return $this->currentObject;
  82 + }
  83 + $this->storeData();
  84 +
  85 + // Check if the entry that has been requested actually exists
  86 + if (!isset($this->cellCache[$pCoord])) {
  87 + // Return null if requested entry doesn't exist in cache
  88 + return null;
  89 + }
  90 +
  91 + // Set current entry to the requested entry
  92 + $this->currentObjectID = $pCoord;
  93 + $this->currentObject = unserialize(gzinflate($this->cellCache[$pCoord]));
  94 + // Re-attach this as the cell's parent
  95 + $this->currentObject->attach($this);
  96 +
  97 + // Return requested entry
  98 + return $this->currentObject;
  99 + }
  100 +
  101 +
  102 + /**
  103 + * Get a list of all cell addresses currently held in cache
  104 + *
  105 + * @return string[]
  106 + */
  107 + public function getCellList()
  108 + {
  109 + if ($this->currentObjectID !== null) {
  110 + $this->storeData();
  111 + }
  112 +
  113 + return parent::getCellList();
  114 + }
  115 +
  116 +
  117 + /**
  118 + * Clear the cell collection and disconnect from our parent
  119 + *
  120 + * @return void
  121 + */
  122 + public function unsetWorksheetCells()
  123 + {
  124 + if (!is_null($this->currentObject)) {
  125 + $this->currentObject->detach();
  126 + $this->currentObject = $this->currentObjectID = null;
  127 + }
  128 + $this->cellCache = array();
  129 +
  130 + // detach ourself from the worksheet, so that it can then delete this object successfully
  131 + $this->parent = null;
  132 + }
  133 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_MemorySerialized
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Store cell data in cache for the current cell object if it's "dirty",
  32 + * and the 'nullify' the current cell object
  33 + *
  34 + * @return void
  35 + * @throws PHPExcel_Exception
  36 + */
  37 + protected function storeData()
  38 + {
  39 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  40 + $this->currentObject->detach();
  41 +
  42 + $this->cellCache[$this->currentObjectID] = serialize($this->currentObject);
  43 + $this->currentCellIsDirty = false;
  44 + }
  45 + $this->currentObjectID = $this->currentObject = null;
  46 + }
  47 +
  48 + /**
  49 + * Add or Update a cell in cache identified by coordinate address
  50 + *
  51 + * @param string $pCoord Coordinate address of the cell to update
  52 + * @param PHPExcel_Cell $cell Cell to update
  53 + * @return PHPExcel_Cell
  54 + * @throws PHPExcel_Exception
  55 + */
  56 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  57 + {
  58 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  59 + $this->storeData();
  60 + }
  61 +
  62 + $this->currentObjectID = $pCoord;
  63 + $this->currentObject = $cell;
  64 + $this->currentCellIsDirty = true;
  65 +
  66 + return $cell;
  67 + }
  68 +
  69 + /**
  70 + * Get cell at a specific coordinate
  71 + *
  72 + * @param string $pCoord Coordinate of the cell
  73 + * @throws PHPExcel_Exception
  74 + * @return PHPExcel_Cell Cell that was found, or null if not found
  75 + */
  76 + public function getCacheData($pCoord)
  77 + {
  78 + if ($pCoord === $this->currentObjectID) {
  79 + return $this->currentObject;
  80 + }
  81 + $this->storeData();
  82 +
  83 + // Check if the entry that has been requested actually exists
  84 + if (!isset($this->cellCache[$pCoord])) {
  85 + // Return null if requested entry doesn't exist in cache
  86 + return null;
  87 + }
  88 +
  89 + // Set current entry to the requested entry
  90 + $this->currentObjectID = $pCoord;
  91 + $this->currentObject = unserialize($this->cellCache[$pCoord]);
  92 + // Re-attach this as the cell's parent
  93 + $this->currentObject->attach($this);
  94 +
  95 + // Return requested entry
  96 + return $this->currentObject;
  97 + }
  98 +
  99 + /**
  100 + * Get a list of all cell addresses currently held in cache
  101 + *
  102 + * @return string[]
  103 + */
  104 + public function getCellList()
  105 + {
  106 + if ($this->currentObjectID !== null) {
  107 + $this->storeData();
  108 + }
  109 +
  110 + return parent::getCellList();
  111 + }
  112 +
  113 + /**
  114 + * Clear the cell collection and disconnect from our parent
  115 + *
  116 + * @return void
  117 + */
  118 + public function unsetWorksheetCells()
  119 + {
  120 + if (!is_null($this->currentObject)) {
  121 + $this->currentObject->detach();
  122 + $this->currentObject = $this->currentObjectID = null;
  123 + }
  124 + $this->cellCache = array();
  125 +
  126 + // detach ourself from the worksheet, so that it can then delete this object successfully
  127 + $this->parent = null;
  128 + }
  129 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_PHPTemp
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Name of the file for this cache
  32 + *
  33 + * @var string
  34 + */
  35 + private $fileHandle = null;
  36 +
  37 + /**
  38 + * Memory limit to use before reverting to file cache
  39 + *
  40 + * @var integer
  41 + */
  42 + private $memoryCacheSize = null;
  43 +
  44 + /**
  45 + * Store cell data in cache for the current cell object if it's "dirty",
  46 + * and the 'nullify' the current cell object
  47 + *
  48 + * @return void
  49 + * @throws PHPExcel_Exception
  50 + */
  51 + protected function storeData()
  52 + {
  53 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  54 + $this->currentObject->detach();
  55 +
  56 + fseek($this->fileHandle, 0, SEEK_END);
  57 +
  58 + $this->cellCache[$this->currentObjectID] = array(
  59 + 'ptr' => ftell($this->fileHandle),
  60 + 'sz' => fwrite($this->fileHandle, serialize($this->currentObject))
  61 + );
  62 + $this->currentCellIsDirty = false;
  63 + }
  64 + $this->currentObjectID = $this->currentObject = null;
  65 + }
  66 +
  67 +
  68 + /**
  69 + * Add or Update a cell in cache identified by coordinate address
  70 + *
  71 + * @param string $pCoord Coordinate address of the cell to update
  72 + * @param PHPExcel_Cell $cell Cell to update
  73 + * @return PHPExcel_Cell
  74 + * @throws PHPExcel_Exception
  75 + */
  76 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  77 + {
  78 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  79 + $this->storeData();
  80 + }
  81 +
  82 + $this->currentObjectID = $pCoord;
  83 + $this->currentObject = $cell;
  84 + $this->currentCellIsDirty = true;
  85 +
  86 + return $cell;
  87 + }
  88 +
  89 +
  90 + /**
  91 + * Get cell at a specific coordinate
  92 + *
  93 + * @param string $pCoord Coordinate of the cell
  94 + * @throws PHPExcel_Exception
  95 + * @return PHPExcel_Cell Cell that was found, or null if not found
  96 + */
  97 + public function getCacheData($pCoord)
  98 + {
  99 + if ($pCoord === $this->currentObjectID) {
  100 + return $this->currentObject;
  101 + }
  102 + $this->storeData();
  103 +
  104 + // Check if the entry that has been requested actually exists
  105 + if (!isset($this->cellCache[$pCoord])) {
  106 + // Return null if requested entry doesn't exist in cache
  107 + return null;
  108 + }
  109 +
  110 + // Set current entry to the requested entry
  111 + $this->currentObjectID = $pCoord;
  112 + fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']);
  113 + $this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz']));
  114 + // Re-attach this as the cell's parent
  115 + $this->currentObject->attach($this);
  116 +
  117 + // Return requested entry
  118 + return $this->currentObject;
  119 + }
  120 +
  121 + /**
  122 + * Get a list of all cell addresses currently held in cache
  123 + *
  124 + * @return string[]
  125 + */
  126 + public function getCellList()
  127 + {
  128 + if ($this->currentObjectID !== null) {
  129 + $this->storeData();
  130 + }
  131 +
  132 + return parent::getCellList();
  133 + }
  134 +
  135 + /**
  136 + * Clone the cell collection
  137 + *
  138 + * @param PHPExcel_Worksheet $parent The new worksheet
  139 + * @return void
  140 + */
  141 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  142 + {
  143 + parent::copyCellCollection($parent);
  144 + // Open a new stream for the cell cache data
  145 + $newFileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+');
  146 + // Copy the existing cell cache data to the new stream
  147 + fseek($this->fileHandle, 0);
  148 + while (!feof($this->fileHandle)) {
  149 + fwrite($newFileHandle, fread($this->fileHandle, 1024));
  150 + }
  151 + $this->fileHandle = $newFileHandle;
  152 + }
  153 +
  154 + /**
  155 + * Clear the cell collection and disconnect from our parent
  156 + *
  157 + * @return void
  158 + */
  159 + public function unsetWorksheetCells()
  160 + {
  161 + if (!is_null($this->currentObject)) {
  162 + $this->currentObject->detach();
  163 + $this->currentObject = $this->currentObjectID = null;
  164 + }
  165 + $this->cellCache = array();
  166 +
  167 + // detach ourself from the worksheet, so that it can then delete this object successfully
  168 + $this->parent = null;
  169 +
  170 + // Close down the php://temp file
  171 + $this->__destruct();
  172 + }
  173 +
  174 + /**
  175 + * Initialise this new cell collection
  176 + *
  177 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  178 + * @param array of mixed $arguments Additional initialisation arguments
  179 + */
  180 + public function __construct(PHPExcel_Worksheet $parent, $arguments)
  181 + {
  182 + $this->memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB';
  183 +
  184 + parent::__construct($parent);
  185 + if (is_null($this->fileHandle)) {
  186 + $this->fileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+');
  187 + }
  188 + }
  189 +
  190 + /**
  191 + * Destroy this cell collection
  192 + */
  193 + public function __destruct()
  194 + {
  195 + if (!is_null($this->fileHandle)) {
  196 + fclose($this->fileHandle);
  197 + }
  198 + $this->fileHandle = null;
  199 + }
  200 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_SQLite
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Database table name
  32 + *
  33 + * @var string
  34 + */
  35 + private $TableName = null;
  36 +
  37 + /**
  38 + * Database handle
  39 + *
  40 + * @var resource
  41 + */
  42 + private $DBHandle = null;
  43 +
  44 + /**
  45 + * Store cell data in cache for the current cell object if it's "dirty",
  46 + * and the 'nullify' the current cell object
  47 + *
  48 + * @return void
  49 + * @throws PHPExcel_Exception
  50 + */
  51 + protected function storeData()
  52 + {
  53 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  54 + $this->currentObject->detach();
  55 +
  56 + if (!$this->DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES('".$this->currentObjectID."','".sqlite_escape_string(serialize($this->currentObject))."')")) {
  57 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  58 + }
  59 + $this->currentCellIsDirty = false;
  60 + }
  61 + $this->currentObjectID = $this->currentObject = null;
  62 + }
  63 +
  64 + /**
  65 + * Add or Update a cell in cache identified by coordinate address
  66 + *
  67 + * @param string $pCoord Coordinate address of the cell to update
  68 + * @param PHPExcel_Cell $cell Cell to update
  69 + * @return PHPExcel_Cell
  70 + * @throws PHPExcel_Exception
  71 + */
  72 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  73 + {
  74 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  75 + $this->storeData();
  76 + }
  77 +
  78 + $this->currentObjectID = $pCoord;
  79 + $this->currentObject = $cell;
  80 + $this->currentCellIsDirty = true;
  81 +
  82 + return $cell;
  83 + }
  84 +
  85 + /**
  86 + * Get cell at a specific coordinate
  87 + *
  88 + * @param string $pCoord Coordinate of the cell
  89 + * @throws PHPExcel_Exception
  90 + * @return PHPExcel_Cell Cell that was found, or null if not found
  91 + */
  92 + public function getCacheData($pCoord)
  93 + {
  94 + if ($pCoord === $this->currentObjectID) {
  95 + return $this->currentObject;
  96 + }
  97 + $this->storeData();
  98 +
  99 + $query = "SELECT value FROM kvp_".$this->TableName." WHERE id='".$pCoord."'";
  100 + $cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC);
  101 + if ($cellResultSet === false) {
  102 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  103 + } elseif ($cellResultSet->numRows() == 0) {
  104 + // Return null if requested entry doesn't exist in cache
  105 + return null;
  106 + }
  107 +
  108 + // Set current entry to the requested entry
  109 + $this->currentObjectID = $pCoord;
  110 +
  111 + $cellResult = $cellResultSet->fetchSingle();
  112 + $this->currentObject = unserialize($cellResult);
  113 + // Re-attach this as the cell's parent
  114 + $this->currentObject->attach($this);
  115 +
  116 + // Return requested entry
  117 + return $this->currentObject;
  118 + }
  119 +
  120 + /**
  121 + * Is a value set for an indexed cell?
  122 + *
  123 + * @param string $pCoord Coordinate address of the cell to check
  124 + * @return boolean
  125 + */
  126 + public function isDataSet($pCoord)
  127 + {
  128 + if ($pCoord === $this->currentObjectID) {
  129 + return true;
  130 + }
  131 +
  132 + // Check if the requested entry exists in the cache
  133 + $query = "SELECT id FROM kvp_".$this->TableName." WHERE id='".$pCoord."'";
  134 + $cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC);
  135 + if ($cellResultSet === false) {
  136 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  137 + } elseif ($cellResultSet->numRows() == 0) {
  138 + // Return null if requested entry doesn't exist in cache
  139 + return false;
  140 + }
  141 + return true;
  142 + }
  143 +
  144 + /**
  145 + * Delete a cell in cache identified by coordinate address
  146 + *
  147 + * @param string $pCoord Coordinate address of the cell to delete
  148 + * @throws PHPExcel_Exception
  149 + */
  150 + public function deleteCacheData($pCoord)
  151 + {
  152 + if ($pCoord === $this->currentObjectID) {
  153 + $this->currentObject->detach();
  154 + $this->currentObjectID = $this->currentObject = null;
  155 + }
  156 +
  157 + // Check if the requested entry exists in the cache
  158 + $query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$pCoord."'";
  159 + if (!$this->DBHandle->queryExec($query)) {
  160 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  161 + }
  162 +
  163 + $this->currentCellIsDirty = false;
  164 + }
  165 +
  166 + /**
  167 + * Move a cell object from one address to another
  168 + *
  169 + * @param string $fromAddress Current address of the cell to move
  170 + * @param string $toAddress Destination address of the cell to move
  171 + * @return boolean
  172 + */
  173 + public function moveCell($fromAddress, $toAddress)
  174 + {
  175 + if ($fromAddress === $this->currentObjectID) {
  176 + $this->currentObjectID = $toAddress;
  177 + }
  178 +
  179 + $query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$toAddress."'";
  180 + $result = $this->DBHandle->exec($query);
  181 + if ($result === false) {
  182 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  183 + }
  184 +
  185 + $query = "UPDATE kvp_".$this->TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'";
  186 + $result = $this->DBHandle->exec($query);
  187 + if ($result === false) {
  188 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  189 + }
  190 +
  191 + return true;
  192 + }
  193 +
  194 + /**
  195 + * Get a list of all cell addresses currently held in cache
  196 + *
  197 + * @return string[]
  198 + */
  199 + public function getCellList()
  200 + {
  201 + if ($this->currentObjectID !== null) {
  202 + $this->storeData();
  203 + }
  204 +
  205 + $query = "SELECT id FROM kvp_".$this->TableName;
  206 + $cellIdsResult = $this->DBHandle->unbufferedQuery($query, SQLITE_ASSOC);
  207 + if ($cellIdsResult === false) {
  208 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  209 + }
  210 +
  211 + $cellKeys = array();
  212 + foreach ($cellIdsResult as $row) {
  213 + $cellKeys[] = $row['id'];
  214 + }
  215 +
  216 + return $cellKeys;
  217 + }
  218 +
  219 + /**
  220 + * Clone the cell collection
  221 + *
  222 + * @param PHPExcel_Worksheet $parent The new worksheet
  223 + * @return void
  224 + */
  225 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  226 + {
  227 + $this->currentCellIsDirty;
  228 + $this->storeData();
  229 +
  230 + // Get a new id for the new table name
  231 + $tableName = str_replace('.', '_', $this->getUniqueID());
  232 + if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)
  233 + AS SELECT * FROM kvp_'.$this->TableName)
  234 + ) {
  235 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  236 + }
  237 +
  238 + // Copy the existing cell cache file
  239 + $this->TableName = $tableName;
  240 + }
  241 +
  242 + /**
  243 + * Clear the cell collection and disconnect from our parent
  244 + *
  245 + * @return void
  246 + */
  247 + public function unsetWorksheetCells()
  248 + {
  249 + if (!is_null($this->currentObject)) {
  250 + $this->currentObject->detach();
  251 + $this->currentObject = $this->currentObjectID = null;
  252 + }
  253 + // detach ourself from the worksheet, so that it can then delete this object successfully
  254 + $this->parent = null;
  255 +
  256 + // Close down the temporary cache file
  257 + $this->__destruct();
  258 + }
  259 +
  260 + /**
  261 + * Initialise this new cell collection
  262 + *
  263 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  264 + */
  265 + public function __construct(PHPExcel_Worksheet $parent)
  266 + {
  267 + parent::__construct($parent);
  268 + if (is_null($this->DBHandle)) {
  269 + $this->TableName = str_replace('.', '_', $this->getUniqueID());
  270 + $_DBName = ':memory:';
  271 +
  272 + $this->DBHandle = new SQLiteDatabase($_DBName);
  273 + if ($this->DBHandle === false) {
  274 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  275 + }
  276 + if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) {
  277 + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError()));
  278 + }
  279 + }
  280 + }
  281 +
  282 + /**
  283 + * Destroy this cell collection
  284 + */
  285 + public function __destruct()
  286 + {
  287 + if (!is_null($this->DBHandle)) {
  288 + $this->DBHandle->queryExec('DROP TABLE kvp_'.$this->TableName);
  289 + }
  290 + $this->DBHandle = null;
  291 + }
  292 +
  293 + /**
  294 + * Identify whether the caching method is currently available
  295 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  296 + *
  297 + * @return boolean
  298 + */
  299 + public static function cacheMethodIsAvailable()
  300 + {
  301 + if (!function_exists('sqlite_open')) {
  302 + return false;
  303 + }
  304 +
  305 + return true;
  306 + }
  307 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_SQLite3
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Database table name
  32 + *
  33 + * @var string
  34 + */
  35 + private $TableName = null;
  36 +
  37 + /**
  38 + * Database handle
  39 + *
  40 + * @var resource
  41 + */
  42 + private $DBHandle = null;
  43 +
  44 + /**
  45 + * Prepared statement for a SQLite3 select query
  46 + *
  47 + * @var SQLite3Stmt
  48 + */
  49 + private $selectQuery;
  50 +
  51 + /**
  52 + * Prepared statement for a SQLite3 insert query
  53 + *
  54 + * @var SQLite3Stmt
  55 + */
  56 + private $insertQuery;
  57 +
  58 + /**
  59 + * Prepared statement for a SQLite3 update query
  60 + *
  61 + * @var SQLite3Stmt
  62 + */
  63 + private $updateQuery;
  64 +
  65 + /**
  66 + * Prepared statement for a SQLite3 delete query
  67 + *
  68 + * @var SQLite3Stmt
  69 + */
  70 + private $deleteQuery;
  71 +
  72 + /**
  73 + * Store cell data in cache for the current cell object if it's "dirty",
  74 + * and the 'nullify' the current cell object
  75 + *
  76 + * @return void
  77 + * @throws PHPExcel_Exception
  78 + */
  79 + protected function storeData()
  80 + {
  81 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  82 + $this->currentObject->detach();
  83 +
  84 + $this->insertQuery->bindValue('id', $this->currentObjectID, SQLITE3_TEXT);
  85 + $this->insertQuery->bindValue('data', serialize($this->currentObject), SQLITE3_BLOB);
  86 + $result = $this->insertQuery->execute();
  87 + if ($result === false) {
  88 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  89 + }
  90 + $this->currentCellIsDirty = false;
  91 + }
  92 + $this->currentObjectID = $this->currentObject = null;
  93 + }
  94 +
  95 + /**
  96 + * Add or Update a cell in cache identified by coordinate address
  97 + *
  98 + * @param string $pCoord Coordinate address of the cell to update
  99 + * @param PHPExcel_Cell $cell Cell to update
  100 + * @return PHPExcel_Cell
  101 + * @throws PHPExcel_Exception
  102 + */
  103 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  104 + {
  105 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  106 + $this->storeData();
  107 + }
  108 +
  109 + $this->currentObjectID = $pCoord;
  110 + $this->currentObject = $cell;
  111 + $this->currentCellIsDirty = true;
  112 +
  113 + return $cell;
  114 + }
  115 +
  116 + /**
  117 + * Get cell at a specific coordinate
  118 + *
  119 + * @param string $pCoord Coordinate of the cell
  120 + * @throws PHPExcel_Exception
  121 + * @return PHPExcel_Cell Cell that was found, or null if not found
  122 + */
  123 + public function getCacheData($pCoord)
  124 + {
  125 + if ($pCoord === $this->currentObjectID) {
  126 + return $this->currentObject;
  127 + }
  128 + $this->storeData();
  129 +
  130 + $this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT);
  131 + $cellResult = $this->selectQuery->execute();
  132 + if ($cellResult === false) {
  133 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  134 + }
  135 + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC);
  136 + if ($cellData === false) {
  137 + // Return null if requested entry doesn't exist in cache
  138 + return null;
  139 + }
  140 +
  141 + // Set current entry to the requested entry
  142 + $this->currentObjectID = $pCoord;
  143 +
  144 + $this->currentObject = unserialize($cellData['value']);
  145 + // Re-attach this as the cell's parent
  146 + $this->currentObject->attach($this);
  147 +
  148 + // Return requested entry
  149 + return $this->currentObject;
  150 + }
  151 +
  152 + /**
  153 + * Is a value set for an indexed cell?
  154 + *
  155 + * @param string $pCoord Coordinate address of the cell to check
  156 + * @return boolean
  157 + */
  158 + public function isDataSet($pCoord)
  159 + {
  160 + if ($pCoord === $this->currentObjectID) {
  161 + return true;
  162 + }
  163 +
  164 + // Check if the requested entry exists in the cache
  165 + $this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT);
  166 + $cellResult = $this->selectQuery->execute();
  167 + if ($cellResult === false) {
  168 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  169 + }
  170 + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC);
  171 +
  172 + return ($cellData === false) ? false : true;
  173 + }
  174 +
  175 + /**
  176 + * Delete a cell in cache identified by coordinate address
  177 + *
  178 + * @param string $pCoord Coordinate address of the cell to delete
  179 + * @throws PHPExcel_Exception
  180 + */
  181 + public function deleteCacheData($pCoord)
  182 + {
  183 + if ($pCoord === $this->currentObjectID) {
  184 + $this->currentObject->detach();
  185 + $this->currentObjectID = $this->currentObject = null;
  186 + }
  187 +
  188 + // Check if the requested entry exists in the cache
  189 + $this->deleteQuery->bindValue('id', $pCoord, SQLITE3_TEXT);
  190 + $result = $this->deleteQuery->execute();
  191 + if ($result === false) {
  192 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  193 + }
  194 +
  195 + $this->currentCellIsDirty = false;
  196 + }
  197 +
  198 + /**
  199 + * Move a cell object from one address to another
  200 + *
  201 + * @param string $fromAddress Current address of the cell to move
  202 + * @param string $toAddress Destination address of the cell to move
  203 + * @return boolean
  204 + */
  205 + public function moveCell($fromAddress, $toAddress)
  206 + {
  207 + if ($fromAddress === $this->currentObjectID) {
  208 + $this->currentObjectID = $toAddress;
  209 + }
  210 +
  211 + $this->deleteQuery->bindValue('id', $toAddress, SQLITE3_TEXT);
  212 + $result = $this->deleteQuery->execute();
  213 + if ($result === false) {
  214 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  215 + }
  216 +
  217 + $this->updateQuery->bindValue('toid', $toAddress, SQLITE3_TEXT);
  218 + $this->updateQuery->bindValue('fromid', $fromAddress, SQLITE3_TEXT);
  219 + $result = $this->updateQuery->execute();
  220 + if ($result === false) {
  221 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  222 + }
  223 +
  224 + return true;
  225 + }
  226 +
  227 + /**
  228 + * Get a list of all cell addresses currently held in cache
  229 + *
  230 + * @return string[]
  231 + */
  232 + public function getCellList()
  233 + {
  234 + if ($this->currentObjectID !== null) {
  235 + $this->storeData();
  236 + }
  237 +
  238 + $query = "SELECT id FROM kvp_".$this->TableName;
  239 + $cellIdsResult = $this->DBHandle->query($query);
  240 + if ($cellIdsResult === false) {
  241 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  242 + }
  243 +
  244 + $cellKeys = array();
  245 + while ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) {
  246 + $cellKeys[] = $row['id'];
  247 + }
  248 +
  249 + return $cellKeys;
  250 + }
  251 +
  252 + /**
  253 + * Clone the cell collection
  254 + *
  255 + * @param PHPExcel_Worksheet $parent The new worksheet
  256 + * @return void
  257 + */
  258 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  259 + {
  260 + $this->currentCellIsDirty;
  261 + $this->storeData();
  262 +
  263 + // Get a new id for the new table name
  264 + $tableName = str_replace('.', '_', $this->getUniqueID());
  265 + if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)
  266 + AS SELECT * FROM kvp_'.$this->TableName)
  267 + ) {
  268 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  269 + }
  270 +
  271 + // Copy the existing cell cache file
  272 + $this->TableName = $tableName;
  273 + }
  274 +
  275 + /**
  276 + * Clear the cell collection and disconnect from our parent
  277 + *
  278 + * @return void
  279 + */
  280 + public function unsetWorksheetCells()
  281 + {
  282 + if (!is_null($this->currentObject)) {
  283 + $this->currentObject->detach();
  284 + $this->currentObject = $this->currentObjectID = null;
  285 + }
  286 + // detach ourself from the worksheet, so that it can then delete this object successfully
  287 + $this->parent = null;
  288 +
  289 + // Close down the temporary cache file
  290 + $this->__destruct();
  291 + }
  292 +
  293 + /**
  294 + * Initialise this new cell collection
  295 + *
  296 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  297 + */
  298 + public function __construct(PHPExcel_Worksheet $parent)
  299 + {
  300 + parent::__construct($parent);
  301 + if (is_null($this->DBHandle)) {
  302 + $this->TableName = str_replace('.', '_', $this->getUniqueID());
  303 + $_DBName = ':memory:';
  304 +
  305 + $this->DBHandle = new SQLite3($_DBName);
  306 + if ($this->DBHandle === false) {
  307 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  308 + }
  309 + if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) {
  310 + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg());
  311 + }
  312 + }
  313 +
  314 + $this->selectQuery = $this->DBHandle->prepare("SELECT value FROM kvp_".$this->TableName." WHERE id = :id");
  315 + $this->insertQuery = $this->DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES(:id,:data)");
  316 + $this->updateQuery = $this->DBHandle->prepare("UPDATE kvp_".$this->TableName." SET id=:toId WHERE id=:fromId");
  317 + $this->deleteQuery = $this->DBHandle->prepare("DELETE FROM kvp_".$this->TableName." WHERE id = :id");
  318 + }
  319 +
  320 + /**
  321 + * Destroy this cell collection
  322 + */
  323 + public function __destruct()
  324 + {
  325 + if (!is_null($this->DBHandle)) {
  326 + $this->DBHandle->exec('DROP TABLE kvp_'.$this->TableName);
  327 + $this->DBHandle->close();
  328 + }
  329 + $this->DBHandle = null;
  330 + }
  331 +
  332 + /**
  333 + * Identify whether the caching method is currently available
  334 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  335 + *
  336 + * @return boolean
  337 + */
  338 + public static function cacheMethodIsAvailable()
  339 + {
  340 + if (!class_exists('SQLite3', false)) {
  341 + return false;
  342 + }
  343 +
  344 + return true;
  345 + }
  346 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorage_Wincache
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
  29 +{
  30 + /**
  31 + * Prefix used to uniquely identify cache data for this worksheet
  32 + *
  33 + * @var string
  34 + */
  35 + private $cachePrefix = null;
  36 +
  37 + /**
  38 + * Cache timeout
  39 + *
  40 + * @var integer
  41 + */
  42 + private $cacheTime = 600;
  43 +
  44 +
  45 + /**
  46 + * Store cell data in cache for the current cell object if it's "dirty",
  47 + * and the 'nullify' the current cell object
  48 + *
  49 + * @return void
  50 + * @throws PHPExcel_Exception
  51 + */
  52 + protected function storeData()
  53 + {
  54 + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
  55 + $this->currentObject->detach();
  56 +
  57 + $obj = serialize($this->currentObject);
  58 + if (wincache_ucache_exists($this->cachePrefix.$this->currentObjectID.'.cache')) {
  59 + if (!wincache_ucache_set($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) {
  60 + $this->__destruct();
  61 + throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache');
  62 + }
  63 + } else {
  64 + if (!wincache_ucache_add($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) {
  65 + $this->__destruct();
  66 + throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache');
  67 + }
  68 + }
  69 + $this->currentCellIsDirty = false;
  70 + }
  71 +
  72 + $this->currentObjectID = $this->currentObject = null;
  73 + }
  74 +
  75 + /**
  76 + * Add or Update a cell in cache identified by coordinate address
  77 + *
  78 + * @param string $pCoord Coordinate address of the cell to update
  79 + * @param PHPExcel_Cell $cell Cell to update
  80 + * @return PHPExcel_Cell
  81 + * @throws PHPExcel_Exception
  82 + */
  83 + public function addCacheData($pCoord, PHPExcel_Cell $cell)
  84 + {
  85 + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
  86 + $this->storeData();
  87 + }
  88 + $this->cellCache[$pCoord] = true;
  89 +
  90 + $this->currentObjectID = $pCoord;
  91 + $this->currentObject = $cell;
  92 + $this->currentCellIsDirty = true;
  93 +
  94 + return $cell;
  95 + }
  96 +
  97 + /**
  98 + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
  99 + *
  100 + * @param string $pCoord Coordinate address of the cell to check
  101 + * @return boolean
  102 + */
  103 + public function isDataSet($pCoord)
  104 + {
  105 + // Check if the requested entry is the current object, or exists in the cache
  106 + if (parent::isDataSet($pCoord)) {
  107 + if ($this->currentObjectID == $pCoord) {
  108 + return true;
  109 + }
  110 + // Check if the requested entry still exists in cache
  111 + $success = wincache_ucache_exists($this->cachePrefix.$pCoord.'.cache');
  112 + if ($success === false) {
  113 + // Entry no longer exists in Wincache, so clear it from the cache array
  114 + parent::deleteCacheData($pCoord);
  115 + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');
  116 + }
  117 + return true;
  118 + }
  119 + return false;
  120 + }
  121 +
  122 +
  123 + /**
  124 + * Get cell at a specific coordinate
  125 + *
  126 + * @param string $pCoord Coordinate of the cell
  127 + * @throws PHPExcel_Exception
  128 + * @return PHPExcel_Cell Cell that was found, or null if not found
  129 + */
  130 + public function getCacheData($pCoord)
  131 + {
  132 + if ($pCoord === $this->currentObjectID) {
  133 + return $this->currentObject;
  134 + }
  135 + $this->storeData();
  136 +
  137 + // Check if the entry that has been requested actually exists
  138 + $obj = null;
  139 + if (parent::isDataSet($pCoord)) {
  140 + $success = false;
  141 + $obj = wincache_ucache_get($this->cachePrefix.$pCoord.'.cache', $success);
  142 + if ($success === false) {
  143 + // Entry no longer exists in WinCache, so clear it from the cache array
  144 + parent::deleteCacheData($pCoord);
  145 + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');
  146 + }
  147 + } else {
  148 + // Return null if requested entry doesn't exist in cache
  149 + return null;
  150 + }
  151 +
  152 + // Set current entry to the requested entry
  153 + $this->currentObjectID = $pCoord;
  154 + $this->currentObject = unserialize($obj);
  155 + // Re-attach this as the cell's parent
  156 + $this->currentObject->attach($this);
  157 +
  158 + // Return requested entry
  159 + return $this->currentObject;
  160 + }
  161 +
  162 +
  163 + /**
  164 + * Get a list of all cell addresses currently held in cache
  165 + *
  166 + * @return string[]
  167 + */
  168 + public function getCellList()
  169 + {
  170 + if ($this->currentObjectID !== null) {
  171 + $this->storeData();
  172 + }
  173 +
  174 + return parent::getCellList();
  175 + }
  176 +
  177 + /**
  178 + * Delete a cell in cache identified by coordinate address
  179 + *
  180 + * @param string $pCoord Coordinate address of the cell to delete
  181 + * @throws PHPExcel_Exception
  182 + */
  183 + public function deleteCacheData($pCoord)
  184 + {
  185 + // Delete the entry from Wincache
  186 + wincache_ucache_delete($this->cachePrefix.$pCoord.'.cache');
  187 +
  188 + // Delete the entry from our cell address array
  189 + parent::deleteCacheData($pCoord);
  190 + }
  191 +
  192 + /**
  193 + * Clone the cell collection
  194 + *
  195 + * @param PHPExcel_Worksheet $parent The new worksheet
  196 + * @return void
  197 + */
  198 + public function copyCellCollection(PHPExcel_Worksheet $parent)
  199 + {
  200 + parent::copyCellCollection($parent);
  201 + // Get a new id for the new file name
  202 + $baseUnique = $this->getUniqueID();
  203 + $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.';
  204 + $cacheList = $this->getCellList();
  205 + foreach ($cacheList as $cellID) {
  206 + if ($cellID != $this->currentObjectID) {
  207 + $success = false;
  208 + $obj = wincache_ucache_get($this->cachePrefix.$cellID.'.cache', $success);
  209 + if ($success === false) {
  210 + // Entry no longer exists in WinCache, so clear it from the cache array
  211 + parent::deleteCacheData($cellID);
  212 + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache');
  213 + }
  214 + if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->cacheTime)) {
  215 + $this->__destruct();
  216 + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache');
  217 + }
  218 + }
  219 + }
  220 + $this->cachePrefix = $newCachePrefix;
  221 + }
  222 +
  223 +
  224 + /**
  225 + * Clear the cell collection and disconnect from our parent
  226 + *
  227 + * @return void
  228 + */
  229 + public function unsetWorksheetCells()
  230 + {
  231 + if (!is_null($this->currentObject)) {
  232 + $this->currentObject->detach();
  233 + $this->currentObject = $this->currentObjectID = null;
  234 + }
  235 +
  236 + // Flush the WinCache cache
  237 + $this->__destruct();
  238 +
  239 + $this->cellCache = array();
  240 +
  241 + // detach ourself from the worksheet, so that it can then delete this object successfully
  242 + $this->parent = null;
  243 + }
  244 +
  245 + /**
  246 + * Initialise this new cell collection
  247 + *
  248 + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
  249 + * @param array of mixed $arguments Additional initialisation arguments
  250 + */
  251 + public function __construct(PHPExcel_Worksheet $parent, $arguments)
  252 + {
  253 + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600;
  254 +
  255 + if (is_null($this->cachePrefix)) {
  256 + $baseUnique = $this->getUniqueID();
  257 + $this->cachePrefix = substr(md5($baseUnique), 0, 8).'.';
  258 + $this->cacheTime = $cacheTime;
  259 +
  260 + parent::__construct($parent);
  261 + }
  262 + }
  263 +
  264 + /**
  265 + * Destroy this cell collection
  266 + */
  267 + public function __destruct()
  268 + {
  269 + $cacheList = $this->getCellList();
  270 + foreach ($cacheList as $cellID) {
  271 + wincache_ucache_delete($this->cachePrefix.$cellID.'.cache');
  272 + }
  273 + }
  274 +
  275 + /**
  276 + * Identify whether the caching method is currently available
  277 + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
  278 + *
  279 + * @return boolean
  280 + */
  281 + public static function cacheMethodIsAvailable()
  282 + {
  283 + if (!function_exists('wincache_ucache_add')) {
  284 + return false;
  285 + }
  286 +
  287 + return true;
  288 + }
  289 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CachedObjectStorageFactory
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_CachedObjectStorage
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CachedObjectStorageFactory
  29 +{
  30 + const cache_in_memory = 'Memory';
  31 + const cache_in_memory_gzip = 'MemoryGZip';
  32 + const cache_in_memory_serialized = 'MemorySerialized';
  33 + const cache_igbinary = 'Igbinary';
  34 + const cache_to_discISAM = 'DiscISAM';
  35 + const cache_to_apc = 'APC';
  36 + const cache_to_memcache = 'Memcache';
  37 + const cache_to_phpTemp = 'PHPTemp';
  38 + const cache_to_wincache = 'Wincache';
  39 + const cache_to_sqlite = 'SQLite';
  40 + const cache_to_sqlite3 = 'SQLite3';
  41 +
  42 + /**
  43 + * Name of the method used for cell cacheing
  44 + *
  45 + * @var string
  46 + */
  47 + private static $cacheStorageMethod = null;
  48 +
  49 + /**
  50 + * Name of the class used for cell cacheing
  51 + *
  52 + * @var string
  53 + */
  54 + private static $cacheStorageClass = null;
  55 +
  56 + /**
  57 + * List of all possible cache storage methods
  58 + *
  59 + * @var string[]
  60 + */
  61 + private static $storageMethods = array(
  62 + self::cache_in_memory,
  63 + self::cache_in_memory_gzip,
  64 + self::cache_in_memory_serialized,
  65 + self::cache_igbinary,
  66 + self::cache_to_phpTemp,
  67 + self::cache_to_discISAM,
  68 + self::cache_to_apc,
  69 + self::cache_to_memcache,
  70 + self::cache_to_wincache,
  71 + self::cache_to_sqlite,
  72 + self::cache_to_sqlite3,
  73 + );
  74 +
  75 + /**
  76 + * Default arguments for each cache storage method
  77 + *
  78 + * @var array of mixed array
  79 + */
  80 + private static $storageMethodDefaultParameters = array(
  81 + self::cache_in_memory => array(
  82 + ),
  83 + self::cache_in_memory_gzip => array(
  84 + ),
  85 + self::cache_in_memory_serialized => array(
  86 + ),
  87 + self::cache_igbinary => array(
  88 + ),
  89 + self::cache_to_phpTemp => array( 'memoryCacheSize' => '1MB'
  90 + ),
  91 + self::cache_to_discISAM => array( 'dir' => null
  92 + ),
  93 + self::cache_to_apc => array( 'cacheTime' => 600
  94 + ),
  95 + self::cache_to_memcache => array( 'memcacheServer' => 'localhost',
  96 + 'memcachePort' => 11211,
  97 + 'cacheTime' => 600
  98 + ),
  99 + self::cache_to_wincache => array( 'cacheTime' => 600
  100 + ),
  101 + self::cache_to_sqlite => array(
  102 + ),
  103 + self::cache_to_sqlite3 => array(
  104 + ),
  105 + );
  106 +
  107 + /**
  108 + * Arguments for the active cache storage method
  109 + *
  110 + * @var array of mixed array
  111 + */
  112 + private static $storageMethodParameters = array();
  113 +
  114 + /**
  115 + * Return the current cache storage method
  116 + *
  117 + * @return string|null
  118 + **/
  119 + public static function getCacheStorageMethod()
  120 + {
  121 + return self::$cacheStorageMethod;
  122 + }
  123 +
  124 + /**
  125 + * Return the current cache storage class
  126 + *
  127 + * @return PHPExcel_CachedObjectStorage_ICache|null
  128 + **/
  129 + public static function getCacheStorageClass()
  130 + {
  131 + return self::$cacheStorageClass;
  132 + }
  133 +
  134 + /**
  135 + * Return the list of all possible cache storage methods
  136 + *
  137 + * @return string[]
  138 + **/
  139 + public static function getAllCacheStorageMethods()
  140 + {
  141 + return self::$storageMethods;
  142 + }
  143 +
  144 + /**
  145 + * Return the list of all available cache storage methods
  146 + *
  147 + * @return string[]
  148 + **/
  149 + public static function getCacheStorageMethods()
  150 + {
  151 + $activeMethods = array();
  152 + foreach (self::$storageMethods as $storageMethod) {
  153 + $cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $storageMethod;
  154 + if (call_user_func(array($cacheStorageClass, 'cacheMethodIsAvailable'))) {
  155 + $activeMethods[] = $storageMethod;
  156 + }
  157 + }
  158 + return $activeMethods;
  159 + }
  160 +
  161 + /**
  162 + * Identify the cache storage method to use
  163 + *
  164 + * @param string $method Name of the method to use for cell cacheing
  165 + * @param array of mixed $arguments Additional arguments to pass to the cell caching class
  166 + * when instantiating
  167 + * @return boolean
  168 + **/
  169 + public static function initialize($method = self::cache_in_memory, $arguments = array())
  170 + {
  171 + if (!in_array($method, self::$storageMethods)) {
  172 + return false;
  173 + }
  174 +
  175 + $cacheStorageClass = 'PHPExcel_CachedObjectStorage_'.$method;
  176 + if (!call_user_func(array( $cacheStorageClass,
  177 + 'cacheMethodIsAvailable'))) {
  178 + return false;
  179 + }
  180 +
  181 + self::$storageMethodParameters[$method] = self::$storageMethodDefaultParameters[$method];
  182 + foreach ($arguments as $k => $v) {
  183 + if (array_key_exists($k, self::$storageMethodParameters[$method])) {
  184 + self::$storageMethodParameters[$method][$k] = $v;
  185 + }
  186 + }
  187 +
  188 + if (self::$cacheStorageMethod === null) {
  189 + self::$cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method;
  190 + self::$cacheStorageMethod = $method;
  191 + }
  192 + return true;
  193 + }
  194 +
  195 + /**
  196 + * Initialise the cache storage
  197 + *
  198 + * @param PHPExcel_Worksheet $parent Enable cell caching for this worksheet
  199 + * @return PHPExcel_CachedObjectStorage_ICache
  200 + **/
  201 + public static function getInstance(PHPExcel_Worksheet $parent)
  202 + {
  203 + $cacheMethodIsAvailable = true;
  204 + if (self::$cacheStorageMethod === null) {
  205 + $cacheMethodIsAvailable = self::initialize();
  206 + }
  207 +
  208 + if ($cacheMethodIsAvailable) {
  209 + $instance = new self::$cacheStorageClass(
  210 + $parent,
  211 + self::$storageMethodParameters[self::$cacheStorageMethod]
  212 + );
  213 + if ($instance !== null) {
  214 + return $instance;
  215 + }
  216 + }
  217 +
  218 + return false;
  219 + }
  220 +
  221 + /**
  222 + * Clear the cache storage
  223 + *
  224 + **/
  225 + public static function finalize()
  226 + {
  227 + self::$cacheStorageMethod = null;
  228 + self::$cacheStorageClass = null;
  229 + self::$storageMethodParameters = array();
  230 + }
  231 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CalcEngine_CyclicReferenceStack
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_Calculation
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CalcEngine_CyclicReferenceStack
  29 +{
  30 + /**
  31 + * The call stack for calculated cells
  32 + *
  33 + * @var mixed[]
  34 + */
  35 + private $stack = array();
  36 +
  37 + /**
  38 + * Return the number of entries on the stack
  39 + *
  40 + * @return integer
  41 + */
  42 + public function count()
  43 + {
  44 + return count($this->stack);
  45 + }
  46 +
  47 + /**
  48 + * Push a new entry onto the stack
  49 + *
  50 + * @param mixed $value
  51 + */
  52 + public function push($value)
  53 + {
  54 + $this->stack[$value] = $value;
  55 + }
  56 +
  57 + /**
  58 + * Pop the last entry from the stack
  59 + *
  60 + * @return mixed
  61 + */
  62 + public function pop()
  63 + {
  64 + return array_pop($this->stack);
  65 + }
  66 +
  67 + /**
  68 + * Test to see if a specified entry exists on the stack
  69 + *
  70 + * @param mixed $value The value to test
  71 + */
  72 + public function onStack($value)
  73 + {
  74 + return isset($this->stack[$value]);
  75 + }
  76 +
  77 + /**
  78 + * Clear the stack
  79 + */
  80 + public function clear()
  81 + {
  82 + $this->stack = array();
  83 + }
  84 +
  85 + /**
  86 + * Return an array of all entries on the stack
  87 + *
  88 + * @return mixed[]
  89 + */
  90 + public function showStack()
  91 + {
  92 + return $this->stack;
  93 + }
  94 +}
  1 +<?php
  2 +
  3 +/**
  4 + * PHPExcel_CalcEngine_Logger
  5 + *
  6 + * Copyright (c) 2006 - 2015 PHPExcel
  7 + *
  8 + * This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU Lesser General Public
  10 + * License as published by the Free Software Foundation; either
  11 + * version 2.1 of the License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16 + * Lesser General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU Lesser General Public
  19 + * License along with this library; if not, write to the Free Software
  20 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21 + *
  22 + * @category PHPExcel
  23 + * @package PHPExcel_Calculation
  24 + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
  25 + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  26 + * @version ##VERSION##, ##DATE##
  27 + */
  28 +class PHPExcel_CalcEngine_Logger
  29 +{
  30 + /**
  31 + * Flag to determine whether a debug log should be generated by the calculation engine
  32 + * If true, then a debug log will be generated
  33 + * If false, then a debug log will not be generated
  34 + *
  35 + * @var boolean
  36 + */
  37 + private $writeDebugLog = false;
  38 +
  39 + /**
  40 + * Flag to determine whether a debug log should be echoed by the calculation engine
  41 + * If true, then a debug log will be echoed
  42 + * If false, then a debug log will not be echoed
  43 + * A debug log can only be echoed if it is generated
  44 + *
  45 + * @var boolean
  46 + */
  47 + private $echoDebugLog = false;
  48 +
  49 + /**
  50 + * The debug log generated by the calculation engine
  51 + *
  52 + * @var string[]
  53 + */
  54 + private $debugLog = array();
  55 +
  56 + /**
  57 + * The calculation engine cell reference stack
  58 + *
  59 + * @var PHPExcel_CalcEngine_CyclicReferenceStack
  60 + */
  61 + private $cellStack;
  62 +
  63 + /**
  64 + * Instantiate a Calculation engine logger
  65 + *
  66 + * @param PHPExcel_CalcEngine_CyclicReferenceStack $stack
  67 + */
  68 + public function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack)
  69 + {
  70 + $this->cellStack = $stack;
  71 + }
  72 +
  73 + /**
  74 + * Enable/Disable Calculation engine logging
  75 + *
  76 + * @param boolean $pValue
  77 + */
  78 + public function setWriteDebugLog($pValue = false)
  79 + {
  80 + $this->writeDebugLog = $pValue;
  81 + }
  82 +
  83 + /**
  84 + * Return whether calculation engine logging is enabled or disabled
  85 + *
  86 + * @return boolean
  87 + */
  88 + public function getWriteDebugLog()
  89 + {
  90 + return $this->writeDebugLog;
  91 + }
  92 +
  93 + /**
  94 + * Enable/Disable echoing of debug log information
  95 + *
  96 + * @param boolean $pValue
  97 + */
  98 + public function setEchoDebugLog($pValue = false)
  99 + {
  100 + $this->echoDebugLog = $pValue;
  101 + }
  102 +
  103 + /**
  104 + * Return whether echoing of debug log information is enabled or disabled
  105 + *
  106 + * @return boolean
  107 + */
  108 + public function getEchoDebugLog()
  109 + {
  110 + return $this->echoDebugLog;
  111 + }
  112 +
  113 + /**
  114 + * Write an entry to the calculation engine debug log
  115 + */
  116 + public function writeDebugLog()
  117 + {
  118 + // Only write the debug log if logging is enabled
  119 + if ($this->writeDebugLog) {
  120 + $message = implode(func_get_args());
  121 + $cellReference = implode(' -> ', $this->cellStack->showStack());
  122 + if ($this->echoDebugLog) {
  123 + echo $cellReference,
  124 + ($this->cellStack->count() > 0 ? ' => ' : ''),
  125 + $message,
  126 + PHP_EOL;
  127 + }
  128 + $this->debugLog[] = $cellReference .
  129 + ($this->cellStack->count() > 0 ? ' => ' : '') .
  130 + $message;
  131 + }
  132 + }
  133 +
  134 + /**
  135 + * Clear the calculation engine debug log
  136 + */
  137 + public function clearLog()
  138 + {
  139 + $this->debugLog = array();
  140 + }
  141 +
  142 + /**
  143 + * Return the calculation engine debug log
  144 + *
  145 + * @return string[]
  146 + */
  147 + public function getLog()
  148 + {
  149 + return $this->debugLog;
  150 + }
  151 +}