<?php
/**
 * Horde_ActiveSync_Request_SyncBase::
 *
 * @license   http://www.horde.org/licenses/gpl GPLv2
 *
 * @copyright 2010-2020 Horde LLC (http://www.horde.org)
 * @author    Michael J Rubinsky <mrubinsk@horde.org>
 * @package   ActiveSync
 */
/**
 * Base class for handling ActiveSync Sync-type requests.
 *
 * @license   http://www.horde.org/licenses/gpl GPLv2
 *
 * @copyright 2010-2020 Horde LLC (http://www.horde.org)
 * @author    Michael J Rubinsky <mrubinsk@horde.org>
 * @package   ActiveSync
 * @internal
 */
abstract class Horde_ActiveSync_Request_SyncBase extends Horde_ActiveSync_Request_Base
{
    /**
     * Parse incoming BODYPARTPREFERENCE options.
     *
     * @param array $options  An array structure to parse the data into.
     */
    protected function _bodyPartPrefs(&$options)
    {
        $options['bodypartprefs'] = array();
        if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_TYPE)) {
            $options['bodypartprefs']['type'] = $this->_decoder->getElementContent();
            // MS-ASAIRS 2.2.2.22.3 type MUST be BODYPREF_TYPE_HTML
            if (!$this->_decoder->getElementEndTag() ||
                $options['bodypartprefs']['type'] != Horde_ActiveSync::BODYPREF_TYPE_HTML) {
                $this->_statusCode = self::STATUS_PROTERROR;
                $this->_handleError($options);
                exit;
            }
        }
        if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_TRUNCATIONSIZE)) {
            $options['bodypartprefs']['truncationsize'] = $this->_decoder->getElementContent();
            if (!$this->_decoder->getElementEndTag()) {
                $this->_statusCode = self::STATUS_PROTERROR;
                $this->_handleError($options);
                exit;
            }
        }

        if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_ALLORNONE)) {
            $options['bodypartprefs']['allornone'] = $this->_decoder->getElementContent();
            // MS-ASAIRS 2.2.2.1.1 - MUST be ignored if no trunction
            // size is set. Note we still must read it if it sent
            // so reading the wbxml stream does not break.
            if (empty($options['bodypartprefs']['truncationsize'])) {
                unset($options['bodypartprefs']['allornone']);
            }
            if (!$this->_decoder->getElementEndTag()) {
                $this->_statusCode = self::STATUS_PROTERROR;
                $this->_handleError($options);
                exit;
            }
        }
        if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_PREVIEW)) {
            $options['bodypartprefs']['preview'] = $this->_decoder->getElementContent();
            // MS-ASAIRS 2.2.2.18.3 - Max size of preview is 255.
            if (!$this->_decoder->getElementEndTag() ||
                $options['bodypartprefs']['preview'] > 255) {

                $this->_statusCode = self::STATUS_PROTERROR;
                $this->_handleError($options);
                exit;
            }
        }
        if (!$this->_decoder->getElementEndTag()) {
            $this->_statusCode = self::STATUS_PROTERROR;
            $this->_handleError($options);
            exit;
        }
    }

    /**
     * Parse incoming BODYPREFERENCE options.
     *
     * @param array  An array structure to parse the values into.
     */
    protected function _bodyPrefs(&$options)
    {
        $body_pref = array();
        if (empty($options['bodyprefs'])) {
            $options['bodyprefs'] = array();
        }
        while (1) {
            if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_TYPE)) {
                $body_pref['type'] = $this->_decoder->getElementContent();
                if (!$this->_decoder->getElementEndTag()) {
                    $this->_statusCode = self::STATUS_PROTERROR;
                    $this->_handleError($options);
                    exit;
                }
            }

            if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_TRUNCATIONSIZE)) {
                $body_pref['truncationsize'] = $this->_decoder->getElementContent();
                if (!$this->_decoder->getElementEndTag()) {
                    $this->_statusCode = self::STATUS_PROTERROR;
                    $this->_handleError($options);
                    exit;
                }
            }

            if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_ALLORNONE)) {
                $body_pref['allornone'] = $this->_decoder->getElementContent();
                if (!$this->_decoder->getElementEndTag()) {
                    $this->_statusCode = self::STATUS_PROTERROR;
                    $this->_handleError($options);
                    exit;
                }
            }

            if ($this->_decoder->getElementStartTag(Horde_ActiveSync::AIRSYNCBASE_PREVIEW)) {
                $body_pref['preview'] = $this->_decoder->getElementContent();
                if (!$this->_decoder->getElementEndTag()) {
                    $this->_statusCode = self::STATUS_PROTERROR;
                    $this->_handleError($options);
                    exit;
                }
            }

            $e = $this->_decoder->peek();
            if ($e[Horde_ActiveSync_Wbxml::EN_TYPE] == Horde_ActiveSync_Wbxml::EN_TYPE_ENDTAG) {
                $this->_decoder->getElementEndTag();
                $options['bodyprefs'][$body_pref['type']] = $body_pref;
                break;
            }
        }
    }

    protected function _rightsManagement(&$collection)
    {
        $collection['rightsmanagement'] = $this->_decoder->getElementContent();
        if (!$this->_decoder->getElementEndTag()) {
            $this->_statusCode = self::STATUS_PROTERROR;
            $this->_handleError($collection);
            exit;
        }
    }

    protected function _mimeSupport(&$collection)
    {
        $collection['mimesupport'] = $this->_decoder->getElementContent();
        if (!$this->_decoder->getElementEndTag()) {
            $this->_statusCode = self::STATUS_PROTERROR;
            $this->_handleError($collection);
            exit;
        }
    }
}
