<?php

namespace MamuzContact\Controller;

use MamuzContact\Feature\CommandInterface;
use Zend\Form\FormInterface;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Stdlib\ResponseInterface;
use Zend\View\Model\ModelInterface;
use Zend\View\Model\ViewModel;

class CommandController extends AbstractActionController
{
    /** @var CommandInterface */
    private $commandService;

    /** @var FormInterface */
    private $contactForm;

    /** @var ModelInterface */
    private $viewModel;

    /**
     * @param CommandInterface $commandService
     * @param FormInterface    $contactForm
     */
    public function __construct(
        CommandInterface $commandService,
        FormInterface $contactForm
    ) {
        $this->commandService = $commandService;
        $this->contactForm = $contactForm;
        $this->viewModel = new ViewModel(array('form' => $this->contactForm));
    }

    /**
     * Persist contact entity
     *
     * @return ModelInterface|ResponseInterface
     */
    public function createAction()
    {
        /** @var \Zend\Http\PhpEnvironment\Request $request */
        $request = $this->getRequest();
        $prg = $this->prg($request->getRequestUri(), true);
        if ($prg instanceof ResponseInterface) {
            return $prg;
        } elseif ($prg === false) {
            return $this->viewModel;
        }

        if ($this->contactForm->setData($prg)->isValid()) {
            /** @var \MamuzContact\Entity\Contact $contact */
            $contact = $this->contactForm->getData();
            $this->commandService->persist($contact);
            $this->viewModel->setVariable('contact', $contact);
        }

        return $this->viewModel;
    }
}


<?php

namespace XQueue\Maileon\API\Contacts;

use XQueue\Maileon\API\Contacts\Permission;
use XQueue\Maileon\API\XML\AbstractXMLWrapper;
use XQueue\Maileon\API\XML\XMLUtils;

/**
 * The wrapper class for a Maileon contact. This class wraps the XML structure.
 *
 * @author Felix Heinrichs | Trusted Mails GmbH | felix.heinrichs@trusted-mails.com
 * @author Marcus Ständer | Trusted Mails GmbH | marcus.staender@trusted-mails.com
 */
class Contact extends AbstractXMLWrapper
{
    public $id;
    public $email;
    public $permission;
    public $external_id;
    public $anonymous;
    public $created;
    public $updated;
    public $standard_fields;
    public $custom_fields;

    /**
     * Constructor initializing default values.
     *
     * @param number $id
     *  The Maileon contact id.
     * @param string $email
     *  The email-address of the contact.
     * @param string $permission
     *  The permission code. 1 = NONE, 2 = SOI, 3 = COI, 4 = DOI, 5 = DOI+, 6 = OTHER.
     * @param string $external_id
     *  The external id to identify the contact.
     * @param boolean $anonymous
     * @param array $standard_fields
     *  An array of standard fields.
     * @param array $custom_fields
     *  An array of custom fields of the contact.
     */
    function __construct(
        $id = null,
        $email = null,
        $permission = NULL,
        $external_id = -1,
        $anonymous = false,
        $standard_fields = array(),
        $custom_fields = array(),
        $created = null,
        $updated = null)
    {
        $this->id = $id;
        $this->email = $email;
        $this->permission = $permission;
        $this->external_id = $external_id;
        $this->anonymous = $anonymous;
        $this->standard_fields = $standard_fields;
        $this->custom_fields = $custom_fields;
        $this->created = $created;
        $this->updated = $updated;
    }

    /**
     * Initialization of the contact from a simple xml element.
     *
     * @param SimpleXMLElement $xmlElement
     *  The xml element that is used to parse the contact from.
     */
    function fromXML($xmlElement)
    {

        if (isset($xmlElement->id)) $this->id = $xmlElement->id;
        $this->email = (string)$xmlElement->email;
        if (isset($xmlElement->permission)) $this->permission = Permission::getPermission((string)$xmlElement->permission);
        if (isset($xmlElement->external_id)) (string)$this->external_id = $xmlElement->external_id;
        if (isset($xmlElement->anonymous)) (string)$this->anonymous = $xmlElement->anonymous;
        if (isset($xmlElement['anonymous'])) $this->anonymous = $xmlElement['anonymous'];

        if (isset($xmlElement->created)) $this->created = $xmlElement->created;
        if (isset($xmlElement->updated)) $this->updated = $xmlElement->updated;

        if (isset($xmlElement->standard_fields)) {
            $this->standard_fields = array();
            foreach ($xmlElement->standard_fields->children() as $field) {
                $this->standard_fields[trim($field->name)] = (string)$field->value; // The trim is required to make a safer string from the object
            }
        }

        if (isset($xmlElement->custom_fields)) {
            foreach ($xmlElement->custom_fields->children() as $field) {
                $this->custom_fields[trim($field->name)] = (string)$field->value; // The trim is required to make a safer string from the object
            }
        }
    }

    /**
     * Serialization to a simple XML element.
     *
     * @param bool $addXMLDeclaration
     *
     * @return \em SimpleXMLElement
     *  Generate a XML element from the contact object.
     */
    function toXML($addXMLDeclaration = true)
    {
        $xmlString = $addXMLDeclaration ? "<?xml version=\"1.0\"?><contact></contact>" : "<contact></contact>";
        $xml = new SimpleXMLElement($xmlString);

        // Some fields are mandatory, especially when setting data to the API
        if (isset($this->id)) $xml->addChild("id", $this->id);

        // As shown in http://stackoverflow.com/questions/17027043/unterminated-entity-reference-php a & char causes trouble with addChild.
        // Use this workaround
        if (isset($this->email)) {
            $emailChild = $xml->addChild("email");
            $xml->email = $this->email;
        }

        if (isset($this->permission)) $xml->addChild("permission", $this->permission->getCode());
        if (isset($this->external_id) && $this->external_id != -1) $xml->addChild("external_id", $this->external_id);
        if (isset($this->anonymous)) $xml->addChild("anonymous", $this->anonymous);

        if (isset($this->created)) $xml->addChild("created", $this->created);
        if (isset($this->updated)) $xml->addChild("updated", $this->updated);

        if (isset($this->standard_fields)) {
            $standard_fields = $xml->addChild("standard_fields");
            foreach ($this->standard_fields as $index => $value) {
                $field = $standard_fields->addChild("field");
                $field->addChild("name", $index);

                XMLUtils::addChildAsCDATA($field, "value", $value);
                //$field->addChild("value", $value);
            }
        }

        if (isset($this->custom_fields)) {
            $customfields = $xml->addChild("custom_fields");
            foreach ($this->custom_fields as $index => $value) {
                $field = $customfields->addChild("field");
                $field->addChild("name", $index);

                XMLUtils::addChildAsCDATA($field, "value", $value);
                //$field->addChild("value", $value);
            }
        }

        return $xml;
    }

    /**
     * Serialization to a simple XML element as string
     *
     * @return \em string
     *  The string representation of the XML document for this contact.
     */
    function toXMLString()
    {
        $xml = $this->toXML();
        return $xml->asXML();
    }

    /**
     * Human readable representation of this wrapper.
     *
     * @return \em string
     *  A human readable version of the contact.
     */
    function __toString()
    {

        // Generate standard field string
        $standard_fields = "";
        if (isset($this->standard_fields)) {
            foreach ($this->standard_fields as $index => $value) {
                $standard_fields .= $index . "=" . $value . ",";
            }
            $standard_fields = rtrim($standard_fields, ',');
        }

        // Generate custom field string
        $customfields = "";
        if (isset($this->custom_fields)) {
            foreach ($this->custom_fields as $index => $value) {
                $customfields .= $index . "=" . $value . ",";
            }
            $customfields = rtrim($customfields, ',');
        }

        $permission = "";
        if (isset($this->permission)) {
            $permission = $this->permission->getCode();
        }

        return "Contact [id=" . $this->id . ", email="
        . $this->email . ", permission=" . $permission . ", external_id=" . $this->external_id
        . ", anonymous=" . (($this->anonymous == true) ? "true" : "false") . ", created=" . $this->created . ", updated=" . $this->updated
        . ", standard_fields={" . $standard_fields . "}, customfields={" . $customfields . "}]";
    }

    /**
     * CSV representation of this wrapper.
     *
     * @return \em string
     *  A csv version of the contact.
     */
    function toCsvString()
    {

        // Generate standard field string
        $standard_fields = "{";
        if (isset($this->standard_fields)) {
            foreach ($this->standard_fields as $index => $value) {
                $standard_fields .= $index . "=" . $value . ",";
            }
            $standard_fields = rtrim($standard_fields, ',');
        }
        $standard_fields .= "}";

        // Generate custom field string
        $customfields = "{";
        if (isset($this->custom_fields)) {
            foreach ($this->custom_fields as $index => $value) {
                $customfields .= $index . "=" . $value . ",";
            }
            $customfields = rtrim($customfields, ',');
        }
        $customfields .= "}";

        $permission = "";
        if (isset($this->permission)) {
            $permission = $this->permission->getCode();
        }

        return $this->id
        . ";" . $this->email
        . ";" . $permission
        . ";" . $this->external_id
        . ";" . (($this->anonymous == true) ? "true" : "false")
        . ";" . $this->created
        . ";" . $this->updated
        . ";\"" . $standard_fields . "\""
        . ";\"" . $customfields . "\"";
    }
}


<?php

namespace PhpOffice\PhpSpreadsheet\Style;

use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;

class Border extends Supervisor
{
    // Border style
    const BORDER_NONE = 'none';
    const BORDER_DASHDOT = 'dashDot';
    const BORDER_DASHDOTDOT = 'dashDotDot';
    const BORDER_DASHED = 'dashed';
    const BORDER_DOTTED = 'dotted';
    const BORDER_DOUBLE = 'double';
    const BORDER_HAIR = 'hair';
    const BORDER_MEDIUM = 'medium';
    const BORDER_MEDIUMDASHDOT = 'mediumDashDot';
    const BORDER_MEDIUMDASHDOTDOT = 'mediumDashDotDot';
    const BORDER_MEDIUMDASHED = 'mediumDashed';
    const BORDER_SLANTDASHDOT = 'slantDashDot';
    const BORDER_THICK = 'thick';
    const BORDER_THIN = 'thin';

    /**
     * Border style.
     *
     * @var string
     */
    protected $borderStyle = self::BORDER_NONE;

    /**
     * Border color.
     *
     * @var Color
     */
    protected $color;

    /**
     * @var int
     */
    public $colorIndex;

    /**
     * Create a new Border.
     *
     * @param bool $isSupervisor Flag indicating if this is a supervisor or not
     *                                    Leave this value at default unless you understand exactly what
     *                                        its ramifications are
     * @param bool $isConditional Flag indicating if this is a conditional style or not
     *                                    Leave this value at default unless you understand exactly what
     *                                        its ramifications are
     */
    public function __construct($isSupervisor = false, $isConditional = false)
    {
        // Supervisor?
        parent::__construct($isSupervisor);

        // Initialise values
        $this->color = new Color(Color::COLOR_BLACK, $isSupervisor);

        // bind parent if we are a supervisor
        if ($isSupervisor) {
            $this->color->bindParent($this, 'color');
        }
    }

    /**
     * Get the shared style component for the currently active cell in currently active sheet.
     * Only used for style supervisor.
     *
     * @throws PhpSpreadsheetException
     *
     * @return Border
     */
    public function getSharedComponent()
    {
        switch ($this->parentPropertyName) {
            case 'allBorders':
            case 'horizontal':
            case 'inside':
            case 'outline':
            case 'vertical':
                throw new PhpSpreadsheetException('Cannot get shared component for a pseudo-border.');

                break;
            case 'bottom':
                return $this->parent->getSharedComponent()->getBottom();
            case 'diagonal':
                return $this->parent->getSharedComponent()->getDiagonal();
            case 'left':
                return $this->parent->getSharedComponent()->getLeft();
            case 'right':
                return $this->parent->getSharedComponent()->getRight();
            case 'top':
                return $this->parent->getSharedComponent()->getTop();
        }
    }

    /**
     * Build style array from subcomponents.
     *
     * @param array $array
     *
     * @return array
     */
    public function getStyleArray($array)
    {
        return $this->parent->getStyleArray([$this->parentPropertyName => $array]);
    }

    /**
     * Apply styles from array.
     *
     * <code>
     * $spreadsheet->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray(
     *        [
     *            'borderStyle' => Border::BORDER_DASHDOT,
     *            'color' => [
     *                'rgb' => '808080'
     *            ]
     *        ]
     * );
     * </code>
     *
     * @param array $pStyles Array containing style information
     *
     * @throws PhpSpreadsheetException
     *
     * @return Border
     */
    public function applyFromArray(array $pStyles)
    {
        if ($this->isSupervisor) {
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));
        } else {
            if (isset($pStyles['borderStyle'])) {
                $this->setBorderStyle($pStyles['borderStyle']);
            }
            if (isset($pStyles['color'])) {
                $this->getColor()->applyFromArray($pStyles['color']);
            }
        }

        return $this;
    }

    /**
     * Get Border style.
     *
     * @return string
     */
    public function getBorderStyle()
    {
        if ($this->isSupervisor) {
            return $this->getSharedComponent()->getBorderStyle();
        }

        return $this->borderStyle;
    }

    /**
     * Set Border style.
     *
     * @param bool|string $pValue
     *                            When passing a boolean, FALSE equates Border::BORDER_NONE
     *                                and TRUE to Border::BORDER_MEDIUM
     *
     * @return Border
     */
    public function setBorderStyle($pValue)
    {
        if (empty($pValue)) {
            $pValue = self::BORDER_NONE;
        } elseif (is_bool($pValue) && $pValue) {
            $pValue = self::BORDER_MEDIUM;
        }
        if ($this->isSupervisor) {
            $styleArray = $this->getStyleArray(['borderStyle' => $pValue]);
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
        } else {
            $this->borderStyle = $pValue;
        }

        return $this;
    }

    /**
     * Get Border Color.
     *
     * @return Color
     */
    public function getColor()
    {
        return $this->color;
    }

    /**
     * Set Border Color.
     *
     * @param Color $pValue
     *
     * @throws PhpSpreadsheetException
     *
     * @return Border
     */
    public function setColor(Color $pValue)
    {
        // make sure parameter is a real color and not a supervisor
        $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;

        if ($this->isSupervisor) {
            $styleArray = $this->getColor()->getStyleArray(['argb' => $color->getARGB()]);
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
        } else {
            $this->color = $color;
        }

        return $this;
    }

    /**
     * Get hash code.
     *
     * @return string Hash code
     */
    public function getHashCode()
    {
        if ($this->isSupervisor) {
            return $this->getSharedComponent()->getHashCode();
        }

        return md5(
            $this->borderStyle .
            $this->color->getHashCode() .
            __CLASS__
        );
    }
}


<?php

namespace Encase;

class ContainerItem {

  public $container;
  public $key;
  public $value;
  public $reifiedValue = null;
  public $initializer = null;

  function __construct($container) {
    $this->container = $container;
  }

  function store($key, $value) {
    $this->key = $key;
    $this->value = $value;
  }

  function inject($object, $origin = null) {
    $container = is_null($origin) ? $this->container : $origin;
    return $container->inject($object);
  }

  function reified() {
    return !is_null($this->reifiedValue);
  }

  function reify() {
    if ($this->reified()) {
      return false;
    }

    if (is_callable($this->value)) {
      $this->reifiedValue = call_user_func($this->value, $this->container);
    } else {
      $this->reifiedValue = $this->value;
    }

    return true;
  }

  function fetch() {
    return $this->reifiedValue;
  }

  /* Public API */
  function instance($origin = null) {
    if (!$this->reified()) {
      $this->reify();
    }

    $object = $this->fetch();
    $this->inject($object, $origin);

    if ($this->hasInitializer()) {
      $this->initialize($object, $origin);
    }

    return $object;
  }

  function hasInitializer() {
    return is_null($this->initializer) === false;
  }

  function initialize($object, $origin = null) {
    if (is_null($origin)) {
      $origin = $this->container;
    }

    call_user_func($this->initializer, $object, $origin);
  }
}

?>


<?php

namespace PhpOffice\PhpSpreadsheet\Reader;

use DateTime;
use DateTimeZone;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Document\Properties;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Settings;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use XMLReader;
use ZipArchive;

class Ods extends BaseReader
{
    /**
     * Create a new Ods Reader instance.
     */
    public function __construct()
    {
        $this->readFilter = new DefaultReadFilter();
    }

    /**
     * Can the current IReader read the file?
     *
     * @param string $pFilename
     *
     * @throws Exception
     *
     * @return bool
     */
    public function canRead($pFilename)
    {
        File::assertFile($pFilename);

        $mimeType = 'UNKNOWN';

        // Load file

        $zip = new ZipArchive();
        if ($zip->open($pFilename) === true) {
            // check if it is an OOXML archive
            $stat = $zip->statName('mimetype');
            if ($stat && ($stat['size'] <= 255)) {
                $mimeType = $zip->getFromName($stat['name']);
            } elseif ($stat = $zip->statName('META-INF/manifest.xml')) {
                $xml = simplexml_load_string(
                    $this->securityScan($zip->getFromName('META-INF/manifest.xml')),
                    'SimpleXMLElement',
                    Settings::getLibXmlLoaderOptions()
                );
                $namespacesContent = $xml->getNamespaces(true);
                if (isset($namespacesContent['manifest'])) {
                    $manifest = $xml->children($namespacesContent['manifest']);
                    foreach ($manifest as $manifestDataSet) {
                        $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']);
                        if ($manifestAttributes->{'full-path'} == '/') {
                            $mimeType = (string) $manifestAttributes->{'media-type'};

                            break;
                        }
                    }
                }
            }

            $zip->close();

            return $mimeType === 'application/vnd.oasis.opendocument.spreadsheet';
        }

        return false;
    }

    /**
     * Reads names of the worksheets from a file, without parsing the whole file to a PhpSpreadsheet object.
     *
     * @param string $pFilename
     *
     * @throws Exception
     *
     * @return string[]
     */
    public function listWorksheetNames($pFilename)
    {
        File::assertFile($pFilename);

        $zip = new ZipArchive();
        if (!$zip->open($pFilename)) {
            throw new Exception('Could not open ' . $pFilename . ' for reading! Error opening file.');
        }

        $worksheetNames = [];

        $xml = new XMLReader();
        $xml->xml(
            $this->securityScanFile('zip://' . realpath($pFilename) . '#content.xml'),
            null,
            Settings::getLibXmlLoaderOptions()
        );
        $xml->setParserProperty(2, true);

        // Step into the first level of content of the XML
        $xml->read();
        while ($xml->read()) {
            // Quickly jump through to the office:body node
            while ($xml->name !== 'office:body') {
                if ($xml->isEmptyElement) {
                    $xml->read();
                } else {
                    $xml->next();
                }
            }
            // Now read each node until we find our first table:table node
            while ($xml->read()) {
                if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
                    // Loop through each table:table node reading the table:name attribute for each worksheet name
                    do {
                        $worksheetNames[] = $xml->getAttribute('table:name');
                        $xml->next();
                    } while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);
                }
            }
        }

        return $worksheetNames;
    }

    /**
     * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns).
     *
     * @param string $pFilename
     *
     * @throws Exception
     *
     * @return array
     */
    public function listWorksheetInfo($pFilename)
    {
        File::assertFile($pFilename);

        $worksheetInfo = [];

        $zip = new ZipArchive();
        if (!$zip->open($pFilename)) {
            throw new Exception('Could not open ' . $pFilename . ' for reading! Error opening file.');
        }

        $xml = new XMLReader();
        $xml->xml(
            $this->securityScanFile('zip://' . realpath($pFilename) . '#content.xml'),
            null,
            Settings::getLibXmlLoaderOptions()
        );
        $xml->setParserProperty(2, true);

        // Step into the first level of content of the XML
        $xml->read();
        while ($xml->read()) {
            // Quickly jump through to the office:body node
            while ($xml->name !== 'office:body') {
                if ($xml->isEmptyElement) {
                    $xml->read();
                } else {
                    $xml->next();
                }
            }
            // Now read each node until we find our first table:table node
            while ($xml->read()) {
                if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
                    $worksheetNames[] = $xml->getAttribute('table:name');

                    $tmpInfo = [
                        'worksheetName' => $xml->getAttribute('table:name'),
                        'lastColumnLetter' => 'A',
                        'lastColumnIndex' => 0,
                        'totalRows' => 0,
                        'totalColumns' => 0,
                    ];

                    // Loop through each child node of the table:table element reading
                    $currCells = 0;
                    do {
                        $xml->read();
                        if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
                            $rowspan = $xml->getAttribute('table:number-rows-repeated');
                            $rowspan = empty($rowspan) ? 1 : $rowspan;
                            $tmpInfo['totalRows'] += $rowspan;
                            $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
                            $currCells = 0;
                            // Step into the row
                            $xml->read();
                            do {
                                if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
                                    if (!$xml->isEmptyElement) {
                                        ++$currCells;
                                        $xml->next();
                                    } else {
                                        $xml->read();
                                    }
                                } elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
                                    $mergeSize = $xml->getAttribute('table:number-columns-repeated');
                                    $currCells += (int) $mergeSize;
                                    $xml->read();
                                }
                            } while ($xml->name != 'table:table-row');
                        }
                    } while ($xml->name != 'table:table');

                    $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
                    $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
                    $tmpInfo['lastColumnLetter'] = Coordinate::stringFromColumnIndex($tmpInfo['lastColumnIndex'] + 1);
                    $worksheetInfo[] = $tmpInfo;
                }
            }
        }

        return $worksheetInfo;
    }

    /**
     * Loads PhpSpreadsheet from file.
     *
     * @param string $pFilename
     *
     * @throws Exception
     *
     * @return Spreadsheet
     */
    public function load($pFilename)
    {
        // Create new Spreadsheet
        $spreadsheet = new Spreadsheet();

        // Load into this instance
        return $this->loadIntoExisting($pFilename, $spreadsheet);
    }

    /**
     * Loads PhpSpreadsheet from file into PhpSpreadsheet instance.
     *
     * @param string $pFilename
     * @param Spreadsheet $spreadsheet
     *
     * @throws Exception
     *
     * @return Spreadsheet
     */
    public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
    {
        File::assertFile($pFilename);

        $timezoneObj = new DateTimeZone('Europe/London');
        $GMT = new \DateTimeZone('UTC');

        $zip = new ZipArchive();
        if (!$zip->open($pFilename)) {
            throw new Exception('Could not open ' . $pFilename . ' for reading! Error opening file.');
        }

        // Meta

        $xml = simplexml_load_string(
            $this->securityScan($zip->getFromName('meta.xml')),
            'SimpleXMLElement',
            Settings::getLibXmlLoaderOptions()
        );
        $namespacesMeta = $xml->getNamespaces(true);

        $docProps = $spreadsheet->getProperties();
        $officeProperty = $xml->children($namespacesMeta['office']);
        foreach ($officeProperty as $officePropertyData) {
            $officePropertyDC = [];
            if (isset($namespacesMeta['dc'])) {
                $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
            }
            foreach ($officePropertyDC as $propertyName => $propertyValue) {
                $propertyValue = (string) $propertyValue;
                switch ($propertyName) {
                    case 'title':
                        $docProps->setTitle($propertyValue);

                        break;
                    case 'subject':
                        $docProps->setSubject($propertyValue);

                        break;
                    case 'creator':
                        $docProps->setCreator($propertyValue);
                        $docProps->setLastModifiedBy($propertyValue);

                        break;
                    case 'date':
                        $creationDate = strtotime($propertyValue);
                        $docProps->setCreated($creationDate);
                        $docProps->setModified($creationDate);

                        break;
                    case 'description':
                        $docProps->setDescription($propertyValue);

                        break;
                }
            }
            $officePropertyMeta = [];
            if (isset($namespacesMeta['dc'])) {
                $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
            }
            foreach ($officePropertyMeta as $propertyName => $propertyValue) {
                $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
                $propertyValue = (string) $propertyValue;
                switch ($propertyName) {
                    case 'initial-creator':
                        $docProps->setCreator($propertyValue);

                        break;
                    case 'keyword':
                        $docProps->setKeywords($propertyValue);

                        break;
                    case 'creation-date':
                        $creationDate = strtotime($propertyValue);
                        $docProps->setCreated($creationDate);

                        break;
                    case 'user-defined':
                        $propertyValueType = Properties::PROPERTY_TYPE_STRING;
                        foreach ($propertyValueAttributes as $key => $value) {
                            if ($key == 'name') {
                                $propertyValueName = (string) $value;
                            } elseif ($key == 'value-type') {
                                switch ($value) {
                                    case 'date':
                                        $propertyValue = Properties::convertProperty($propertyValue, 'date');
                                        $propertyValueType = Properties::PROPERTY_TYPE_DATE;

                                        break;
                                    case 'boolean':
                                        $propertyValue = Properties::convertProperty($propertyValue, 'bool');
                                        $propertyValueType = Properties::PROPERTY_TYPE_BOOLEAN;

                                        break;
                                    case 'float':
                                        $propertyValue = Properties::convertProperty($propertyValue, 'r4');
                                        $propertyValueType = Properties::PROPERTY_TYPE_FLOAT;

                                        break;
                                    default:
                                        $propertyValueType = Properties::PROPERTY_TYPE_STRING;
                                }
                            }
                        }
                        $docProps->setCustomProperty($propertyValueName, $propertyValue, $propertyValueType);

                        break;
                }
            }
        }

        // Content

        $dom = new \DOMDocument('1.01', 'UTF-8');
        $dom->loadXML(
            $this->securityScan($zip->getFromName('content.xml')),
            Settings::getLibXmlLoaderOptions()
        );

        $officeNs = $dom->lookupNamespaceUri('office');
        $tableNs = $dom->lookupNamespaceUri('table');
        $textNs = $dom->lookupNamespaceUri('text');
        $xlinkNs = $dom->lookupNamespaceUri('xlink');

        $spreadsheets = $dom->getElementsByTagNameNS($officeNs, 'body')
            ->item(0)
            ->getElementsByTagNameNS($officeNs, 'spreadsheet');

        foreach ($spreadsheets as $workbookData) {
            /** @var \DOMElement $workbookData */
            $tables = $workbookData->getElementsByTagNameNS($tableNs, 'table');

            $worksheetID = 0;
            foreach ($tables as $worksheetDataSet) {
                /** @var \DOMElement $worksheetDataSet */
                $worksheetName = $worksheetDataSet->getAttributeNS($tableNs, 'name');

                // Check loadSheetsOnly
                if (isset($this->loadSheetsOnly)
                    && $worksheetName
                    && !in_array($worksheetName, $this->loadSheetsOnly)) {
                    continue;
                }

                // Create sheet
                if ($worksheetID > 0) {
                    $spreadsheet->createSheet(); // First sheet is added by default
                }
                $spreadsheet->setActiveSheetIndex($worksheetID);

                if ($worksheetName) {
                    // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in
                    // formula cells... during the load, all formulae should be correct, and we're simply
                    // bringing the worksheet name in line with the formula, not the reverse
                    $spreadsheet->getActiveSheet()->setTitle($worksheetName, false, false);
                }

                // Go through every child of table element
                $rowID = 1;
                foreach ($worksheetDataSet->childNodes as $childNode) {
                    /** @var \DOMElement $childNode */

                    // Filter elements which are not under the "table" ns
                    if ($childNode->namespaceURI != $tableNs) {
                        continue;
                    }

                    $key = $childNode->nodeName;

                    // Remove ns from node name
                    if (strpos($key, ':') !== false) {
                        $keyChunks = explode(':', $key);
                        $key = array_pop($keyChunks);
                    }

                    switch ($key) {
                        case 'table-header-rows':
                            /// TODO :: Figure this out. This is only a partial implementation I guess.
                            //          ($rowData it's not used at all and I'm not sure that PHPExcel
                            //          has an API for this)

//                            foreach ($rowData as $keyRowData => $cellData) {
//                                $rowData = $cellData;
//                                break;
//                            }
                            break;
                        case 'table-row':
                            if ($childNode->hasAttributeNS($tableNs, 'number-rows-repeated')) {
                                $rowRepeats = $childNode->getAttributeNS($tableNs, 'number-rows-repeated');
                            } else {
                                $rowRepeats = 1;
                            }

                            $columnID = 'A';
                            foreach ($childNode->childNodes as $key => $cellData) {
                                // @var \DOMElement $cellData

                                if ($this->getReadFilter() !== null) {
                                    if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {
                                        ++$columnID;

                                        continue;
                                    }
                                }

                                // Initialize variables
                                $formatting = $hyperlink = null;
                                $hasCalculatedValue = false;
                                $cellDataFormula = '';

                                if ($cellData->hasAttributeNS($tableNs, 'formula')) {
                                    $cellDataFormula = $cellData->getAttributeNS($tableNs, 'formula');
                                    $hasCalculatedValue = true;
                                }

                                // Annotations
                                $annotation = $cellData->getElementsByTagNameNS($officeNs, 'annotation');

                                if ($annotation->length > 0) {
                                    $textNode = $annotation->item(0)->getElementsByTagNameNS($textNs, 'p');

                                    if ($textNode->length > 0) {
                                        $text = $this->scanElementForText($textNode->item(0));

                                        $spreadsheet->getActiveSheet()
                                            ->getComment($columnID . $rowID)
                                            ->setText($this->parseRichText($text));
//                                                                    ->setAuthor( $author )
                                    }
                                }

                                // Content

                                /** @var \DOMElement[] $paragraphs */
                                $paragraphs = [];

                                foreach ($cellData->childNodes as $item) {
                                    /** @var \DOMElement $item */

                                    // Filter text:p elements
                                    if ($item->nodeName == 'text:p') {
                                        $paragraphs[] = $item;
                                    }
                                }

                                if (count($paragraphs) > 0) {
                                    // Consolidate if there are multiple p records (maybe with spans as well)
                                    $dataArray = [];

                                    // Text can have multiple text:p and within those, multiple text:span.
                                    // text:p newlines, but text:span does not.
                                    // Also, here we assume there is no text data is span fields are specified, since
                                    // we have no way of knowing proper positioning anyway.

                                    foreach ($paragraphs as $pData) {
                                        $dataArray[] = $this->scanElementForText($pData);
                                    }
                                    $allCellDataText = implode($dataArray, "\n");

                                    $type = $cellData->getAttributeNS($officeNs, 'value-type');

                                    switch ($type) {
                                        case 'string':
                                            $type = DataType::TYPE_STRING;
                                            $dataValue = $allCellDataText;

                                            foreach ($paragraphs as $paragraph) {
                                                $link = $paragraph->getElementsByTagNameNS($textNs, 'a');
                                                if ($link->length > 0) {
                                                    $hyperlink = $link->item(0)->getAttributeNS($xlinkNs, 'href');
                                                }
                                            }

                                            break;
                                        case 'boolean':
                                            $type = DataType::TYPE_BOOL;
                                            $dataValue = ($allCellDataText == 'TRUE') ? true : false;

                                            break;
                                        case 'percentage':
                                            $type = DataType::TYPE_NUMERIC;
                                            $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value');

                                            if (floor($dataValue) == $dataValue) {
                                                $dataValue = (int) $dataValue;
                                            }
                                            $formatting = NumberFormat::FORMAT_PERCENTAGE_00;

                                            break;
                                        case 'currency':
                                            $type = DataType::TYPE_NUMERIC;
                                            $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value');

                                            if (floor($dataValue) == $dataValue) {
                                                $dataValue = (int) $dataValue;
                                            }
                                            $formatting = NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;

                                            break;
                                        case 'float':
                                            $type = DataType::TYPE_NUMERIC;
                                            $dataValue = (float) $cellData->getAttributeNS($officeNs, 'value');

                                            if (floor($dataValue) == $dataValue) {
                                                if ($dataValue == (int) $dataValue) {
                                                    $dataValue = (int) $dataValue;
                                                } else {
                                                    $dataValue = (float) $dataValue;
                                                }
                                            }

                                            break;
                                        case 'date':
                                            $type = DataType::TYPE_NUMERIC;
                                            $value = $cellData->getAttributeNS($officeNs, 'date-value');

                                            $dateObj = new DateTime($value, $GMT);
                                            $dateObj->setTimeZone($timezoneObj);
                                            list($year, $month, $day, $hour, $minute, $second) = explode(
                                                ' ',
                                                $dateObj->format('Y m d H i s')
                                            );

                                            $dataValue = Date::formattedPHPToExcel(
                                                $year,
                                                $month,
                                                $day,
                                                $hour,
                                                $minute,
                                                $second
                                            );

                                            if ($dataValue != floor($dataValue)) {
                                                $formatting = NumberFormat::FORMAT_DATE_XLSX15
                                                    . ' '
                                                    . NumberFormat::FORMAT_DATE_TIME4;
                                            } else {
                                                $formatting = NumberFormat::FORMAT_DATE_XLSX15;
                                            }

                                            break;
                                        case 'time':
                                            $type = DataType::TYPE_NUMERIC;

                                            $timeValue = $cellData->getAttributeNS($officeNs, 'time-value');

                                            $dataValue = Date::PHPToExcel(
                                                strtotime(
                                                    '01-01-1970 ' . implode(':', sscanf($timeValue, 'PT%dH%dM%dS'))
                                                )
                                            );
                                            $formatting = NumberFormat::FORMAT_DATE_TIME4;

                                            break;
                                        default:
                                            $dataValue = null;
                                    }
                                } else {
                                    $type = DataType::TYPE_NULL;
                                    $dataValue = null;
                                }

                                if ($hasCalculatedValue) {
                                    $type = DataType::TYPE_FORMULA;
                                    $cellDataFormula = substr($cellDataFormula, strpos($cellDataFormula, ':=') + 1);
                                    $temp = explode('"', $cellDataFormula);
                                    $tKey = false;
                                    foreach ($temp as &$value) {
                                        // Only replace in alternate array entries (i.e. non-quoted blocks)
                                        if ($tKey = !$tKey) {
                                            // Cell range reference in another sheet
                                            $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/U', '$1!$2:$3', $value);

                                            // Cell reference in another sheet
                                            $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/U', '$1!$2', $value);

                                            // Cell range reference
                                            $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/U', '$1:$2', $value);

                                            // Simple cell reference
                                            $value = preg_replace('/\[\.([^\.]+)\]/U', '$1', $value);

                                            $value = Calculation::translateSeparator(';', ',', $value, $inBraces);
                                        }
                                    }
                                    unset($value);

                                    // Then rebuild the formula string
                                    $cellDataFormula = implode('"', $temp);
                                }

                                if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) {
                                    $colRepeats = (int) $cellData->getAttributeNS($tableNs, 'number-columns-repeated');
                                } else {
                                    $colRepeats = 1;
                                }

                                if ($type !== null) {
                                    for ($i = 0; $i < $colRepeats; ++$i) {
                                        if ($i > 0) {
                                            ++$columnID;
                                        }

                                        if ($type !== DataType::TYPE_NULL) {
                                            for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) {
                                                $rID = $rowID + $rowAdjust;

                                                $cell = $spreadsheet->getActiveSheet()
                                                    ->getCell($columnID . $rID);

                                                // Set value
                                                if ($hasCalculatedValue) {
                                                    $cell->setValueExplicit($cellDataFormula, $type);
                                                } else {
                                                    $cell->setValueExplicit($dataValue, $type);
                                                }

                                                if ($hasCalculatedValue) {
                                                    $cell->setCalculatedValue($dataValue);
                                                }

                                                // Set other properties
                                                if ($formatting !== null) {
                                                    $spreadsheet->getActiveSheet()
                                                        ->getStyle($columnID . $rID)
                                                        ->getNumberFormat()
                                                        ->setFormatCode($formatting);
                                                } else {
                                                    $spreadsheet->getActiveSheet()
                                                        ->getStyle($columnID . $rID)
                                                        ->getNumberFormat()
                                                        ->setFormatCode(NumberFormat::FORMAT_GENERAL);
                                                }

                                                if ($hyperlink !== null) {
                                                    $cell->getHyperlink()
                                                        ->setUrl($hyperlink);
                                                }
                                            }
                                        }
                                    }
                                }

                                // Merged cells
                                if ($cellData->hasAttributeNS($tableNs, 'number-columns-spanned')
                                    || $cellData->hasAttributeNS($tableNs, 'number-rows-spanned')
                                ) {
                                    if (($type !== DataType::TYPE_NULL) || (!$this->readDataOnly)) {
                                        $columnTo = $columnID;

                                        if ($cellData->hasAttributeNS($tableNs, 'number-columns-spanned')) {
                                            $columnIndex = Coordinate::columnIndexFromString($columnID);
                                            $columnIndex += (int) $cellData->getAttributeNS($tableNs, 'number-columns-spanned');
                                            $columnIndex -= 2;

                                            $columnTo = Coordinate::stringFromColumnIndex($columnIndex + 1);
                                        }

                                        $rowTo = $rowID;

                                        if ($cellData->hasAttributeNS($tableNs, 'number-rows-spanned')) {
                                            $rowTo = $rowTo + (int) $cellData->getAttributeNS($tableNs, 'number-rows-spanned') - 1;
                                        }

                                        $cellRange = $columnID . $rowID . ':' . $columnTo . $rowTo;
                                        $spreadsheet->getActiveSheet()->mergeCells($cellRange);
                                    }
                                }

                                ++$columnID;
                            }
                            $rowID += $rowRepeats;

                            break;
                    }
                }
                ++$worksheetID;
            }
        }

        // Return
        return $spreadsheet;
    }

    /**
     * Recursively scan element.
     *
     * @param \DOMNode $element
     *
     * @return string
     */
    protected function scanElementForText(\DOMNode $element)
    {
        $str = '';
        foreach ($element->childNodes as $child) {
            /** @var \DOMNode $child */
            if ($child->nodeType == XML_TEXT_NODE) {
                $str .= $child->nodeValue;
            } elseif ($child->nodeType == XML_ELEMENT_NODE && $child->nodeName == 'text:s') {
                // It's a space

                // Multiple spaces?
                /** @var \DOMAttr $cAttr */
                $cAttr = $child->attributes->getNamedItem('c');
                if ($cAttr) {
                    $multiplier = (int) $cAttr->nodeValue;
                } else {
                    $multiplier = 1;
                }

                $str .= str_repeat(' ', $multiplier);
            }

            if ($child->hasChildNodes()) {
                $str .= $this->scanElementForText($child);
            }
        }

        return $str;
    }

    /**
     * @param string $is
     *
     * @return RichText
     */
    private function parseRichText($is)
    {
        $value = new RichText();
        $value->createText($is);

        return $value;
    }
}


<?php

namespace PhpOffice\PhpSpreadsheet;

class HashTable
{
    /**
     * HashTable elements.
     *
     * @var IComparable[]
     */
    protected $items = [];

    /**
     * HashTable key map.
     *
     * @var string[]
     */
    protected $keyMap = [];

    /**
     * Create a new \PhpOffice\PhpSpreadsheet\HashTable.
     *
     * @param IComparable[] $pSource Optional source array to create HashTable from
     *
     * @throws Exception
     */
    public function __construct($pSource = null)
    {
        if ($pSource !== null) {
            // Create HashTable
            $this->addFromSource($pSource);
        }
    }

    /**
     * Add HashTable items from source.
     *
     * @param IComparable[] $pSource Source array to create HashTable from
     *
     * @throws Exception
     */
    public function addFromSource(array $pSource = null)
    {
        // Check if an array was passed
        if ($pSource == null) {
            return;
        }

        foreach ($pSource as $item) {
            $this->add($item);
        }
    }

    /**
     * Add HashTable item.
     *
     * @param IComparable $pSource Item to add
     */
    public function add(IComparable $pSource)
    {
        $hash = $pSource->getHashCode();
        if (!isset($this->items[$hash])) {
            $this->items[$hash] = $pSource;
            $this->keyMap[count($this->items) - 1] = $hash;
        }
    }

    /**
     * Remove HashTable item.
     *
     * @param IComparable $pSource Item to remove
     */
    public function remove(IComparable $pSource)
    {
        $hash = $pSource->getHashCode();
        if (isset($this->items[$hash])) {
            unset($this->items[$hash]);

            $deleteKey = -1;
            foreach ($this->keyMap as $key => $value) {
                if ($deleteKey >= 0) {
                    $this->keyMap[$key - 1] = $value;
                }

                if ($value == $hash) {
                    $deleteKey = $key;
                }
            }
            unset($this->keyMap[count($this->keyMap) - 1]);
        }
    }

    /**
     * Clear HashTable.
     */
    public function clear()
    {
        $this->items = [];
        $this->keyMap = [];
    }

    /**
     * Count.
     *
     * @return int
     */
    public function count()
    {
        return count($this->items);
    }

    /**
     * Get index for hash code.
     *
     * @param string $pHashCode
     *
     * @return int Index
     */
    public function getIndexForHashCode($pHashCode)
    {
        return array_search($pHashCode, $this->keyMap);
    }

    /**
     * Get by index.
     *
     * @param int $pIndex
     *
     * @return IComparable
     */
    public function getByIndex($pIndex)
    {
        if (isset($this->keyMap[$pIndex])) {
            return $this->getByHashCode($this->keyMap[$pIndex]);
        }

        return null;
    }

    /**
     * Get by hashcode.
     *
     * @param string $pHashCode
     *
     * @return IComparable
     */
    public function getByHashCode($pHashCode)
    {
        if (isset($this->items[$pHashCode])) {
            return $this->items[$pHashCode];
        }

        return null;
    }

    /**
     * HashTable to array.
     *
     * @return IComparable[]
     */
    public function toArray()
    {
        return $this->items;
    }

    /**
     * Implement PHP __clone to create a deep clone, not just a shallow copy.
     */
    public function __clone()
    {
        $vars = get_object_vars($this);
        foreach ($vars as $key => $value) {
            if (is_object($value)) {
                $this->$key = clone $value;
            }
        }
    }
}