/home/ivoiecob/email.hirewise-va.com/modules/Contacts/Classes/Csv/Formatter.php
<?php
/**
 * This code is licensed under AGPLv3 license or Afterlogic Software License
 * if commercial version of the product was purchased.
 * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
 */

namespace Aurora\Modules\Contacts\Classes\Csv;

/**
 * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
 * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
 * @copyright Copyright (c) 2023, Afterlogic Corp.
 *
 * @internal
 *
 * @package Contacts
 * @subpackage Helpers
 */
class Formatter
{
    public const CRLF = "\r\n";

    /**
     * @var array
     */
    protected $aMap;

    /**
     * @var string
     */
    protected $sValue;

    /**
     * @var string
     */
    protected $sDelimiter;

    /**
     * @var bool
     */
    protected $bIsHeadersInit;

    /**
     * @var mixed
     */
    protected $oContainer;

    public function __construct()
    {
        $this->sDelimiter = ',';

        $this->sValue = '';
        $this->oContainer = null;
        $this->bIsHeadersInit = false;

        $this->aMap = array(
            'tokens' => array(
                'Title' => 'Title',
                'First Name' => 'FirstName',
                'Middle Name' => '',
                'Last Name' => 'LastName',
                'Nick Name' => 'NickName',
                'Display Name' => 'FullName',
                'Company' => 'BusinessCompany',
                'Department' => 'BusinessDepartment',
                'Job Title' => 'BusinessJobTitle',
                'Business Email' => 'BusinessEmail',
                'Business Street' => 'BusinessAddress',
                'Business City' => 'BusinessCity',
                'Business State' => 'BusinessState',
                'Business Postal Code' => 'BusinessZip',
                'Business Country' => 'BusinessCountry',
                'Home Street' => 'PersonalAddress',
                'Home City' => 'PersonalCity',
                'Home State' => 'PersonalState',
                'Home Postal Code' => 'PersonalZip',
                'Home Country' => 'PersonalCountry',
                'Business Fax' => 'BusinessFax',
                'Business Phone' => 'BusinessPhone',
                'Home Fax' => 'PersonalFax',
                'Home Phone' => 'PersonalPhone',
                'Mobile Phone' => 'PersonalMobile',
                'E-mail Address' => 'PersonalEmail',
                'Notes' => 'Notes',
                'Other Email' => 'OtherEmail',
                'Office Location' => 'BusinessOffice',
                'Web Page' => 'PersonalWeb'
            ),

            'tokensWithSpecialTreatment' => array(
                'Birthday' => array('bdayForm', 'BirthDay', 'BirthMonth', 'BirthYear'),
            )
        );
    }

    public function clear()
    {
        $this->sValue = '';
        $this->oContainer = null;
        $this->bIsHeadersInit = false;
    }

    /**
     * @param string $sDelimiter
     */
    public function setDelimiter($sDelimiter)
    {
        $this->sDelimiter = $sDelimiter;
    }

    /**
     * @return bool
     */
    public function form()
    {
        $this->sValue = '';
        $this->formHeader();
        $this->formTokens();
        return true;
    }

    /**
     * @return void
     */
    protected function formHeader()
    {
        if (!$this->bIsHeadersInit && isset($this->aMap['tokens']) && is_array($this->aMap['tokens'])) {
            $aList = array();
            foreach ($this->aMap['tokens'] as $sToken => $sPropertyName) {
                $aList[] = $this->escapeValue($sToken, true);
            }

            foreach ($this->aMap['tokensWithSpecialTreatment'] as $sToken => $mProperties) {
                $aList[] = $this->escapeValue($sToken, true);
            }

            $this->sValue .= implode($this->sDelimiter, $aList);
            $this->sValue .= \Aurora\Modules\Contacts\Classes\Csv\Formatter::CRLF;

            $this->bIsHeadersInit = true;
        }
    }

    /**
     * @return void
     */
    protected function formTokens()
    {
        if ($this->bIsHeadersInit && isset($this->aMap['tokens']) && is_array($this->aMap['tokens'])) {
            $aList = array();
            foreach ($this->aMap['tokens'] as $sToken => $sPropertyName) {
                if (!empty($sPropertyName)) {
                    $aList[] = $this->escapeValue($this->oContainer->{$sPropertyName}, true);
                } else {
                    $aList[] = $this->escapeValue('', true);
                }
            }

            foreach ($this->aMap['tokensWithSpecialTreatment'] as $sToken => $aParams) {
                $sFunctionName = $aParams[0];
                $aParams[0] = $sToken;

                $mValue = (string) @call_user_func_array(array(&$this, $sFunctionName), $aParams);
                $aList[] = $this->escapeValue($mValue, true);
            }

            $this->sValue .= implode($this->sDelimiter, $aList);
            $this->sValue .= \Aurora\Modules\Contacts\Classes\Csv\Formatter::CRLF;

            $this->bIsHeadersInit = true;
        }
    }

    /**
     * @param mixed $oContainer
     */
    public function setContainer($oContainer)
    {
        $this->oContainer = $oContainer;
    }

    /**
     * @return string
     */
    public function getValue()
    {
        return $this->sValue;
    }

    /**
     * @param string $sToken
     * @param string $sDayFieldName
     * @param string $sMonthFieldName
     * @param string $sYearFieldName
     *
     * @return string
     */
    protected function bdayForm($sToken, $sDayFieldName, $sMonthFieldName, $sYearFieldName)
    {
        $iMonth = $iDay = $iYear = 0;
        if ($this->oContainer) {
            $iDay = $this->oContainer->{$sDayFieldName} ?? 0;
            $iMonth = $this->oContainer->{$sMonthFieldName} ?? 0;
            $iYear = $this->oContainer->{$sYearFieldName} ?? 0;
        }

        return checkdate($iMonth, $iDay, $iYear) ? $iDay . '/' . $iMonth . '/' . $iYear : '';
    }

    /**
     * @param string $sValue
     * @param bool $bAddQuotation Default value is **false**.
     *
     * @return string
     */
    protected function escapeValue($sValue, $bAddQuotation = false)
    {
        $sValue = $sValue !== null ? $sValue : '';
        $sValue = str_replace('"', '""', $sValue);
        return $bAddQuotation ?
            (empty($sValue) ? '' : '"' . $sValue . '"') : $sValue;
    }
}