<?php

/*
+---------------------------------------------------------------------------+
| Revive Adserver                                                           |
| http://www.revive-adserver.com                                            |
|                                                                           |
| Copyright: See the COPYRIGHT.txt file.                                    |
| License: GPLv2 or later, see the LICENSE.txt file.                        |
+---------------------------------------------------------------------------+
*/

require_once MAX_PATH . '/lib/OA/Admin/Statistics/Delivery/CommonEntity.php';

/**
 * A common class that defines a common "interface" and common methods for
 * classes that display cross-entity delivery statistics.
 *
 * @package    OpenXAdmin
 * @subpackage StatisticsDelivery
 */
abstract class OA_Admin_Statistics_Delivery_CommonCrossEntity extends OA_Admin_Statistics_Delivery_CommonEntity
{
    public $aAnonAdvertisers;
    public $aAnonPlacements;

    /**
     * PHP5-style constructor
     */
    public function __construct($params)
    {
        // Override links
        $this->entityLinks = [];

        parent::__construct($params);
    }

    /**
     * Merge aggregate stats with entity properties (name, children, etc)
     *
     * The overridden method also takes care to remove inactive entities
     * and to enforce the anonymous properties when logged in as advertiser
     * or publisher
     *
     * @param array Query parameters
     * @param string Key name
     * @return array Full entity stats with entity data
     */
    public function mergeData($aParams, $key)
    {
        $aEntitiesData = parent::mergeData($aParams, $key);

        if ((OA_Permission::isAccount(OA_ACCOUNT_ADVERTISER) || OA_Permission::isAccount(OA_ACCOUNT_TRAFFICKER)) && is_null($this->aAnonAdvertisers)) {
            $this->aAnonAdvertisers = [];
            $this->aAnonPlacements = [];
            $aPlacements = Admin_DA::fromCache('getPlacements', ['placement_anonymous' => 't']);
            foreach ($aPlacements as $placementId => $placement) {
                $this->aAnonAdvertisers[$placement['advertiser_id']] = true;
                $this->aAnonPlacements[$placementId] = true;
            }
        }

        foreach (array_keys($aEntitiesData) as $entityId) {
            if (!isset($this->data[$key][$entityId])) {
                unset($aEntitiesData[$entityId]);
            } elseif ($key == 'advertiser_id' && isset($this->aAnonAdvertisers[$entityId])) {
                $aEntitiesData[$entityId]['hidden'] = true;
            } elseif ($key == 'placement_id' && isset($this->aAnonPlacements[$entityId])) {
                $aEntitiesData[$entityId]['hidden'] = true;
            } elseif ($key == 'ad_id' && isset($this->aAnonPlacements[$aEntitiesData[$entityId]['placement_id']])) {
                $aEntitiesData[$entityId]['hidden'] = true;
            } elseif (OA_Permission::isAccount(OA_ACCOUNT_ADVERTISER)) {
                if (isset($aParams['placement_id'])) {
                    $aEntitiesData[$entityId]['hidden'] = isset($this->aAnonPlacements[$aParams['placement_id']]);
                } else {
                    $aEntitiesData[$entityId]['hidden'] = isset($this->aAnonAdvertisers[OA_Permission::getEntityId()]);
                }
            }
        }

        return $aEntitiesData;
    }

    /**
     * Fixes link parameters to include cross-entities
     *
     * @param array Entities array
     */
    public function fixLinkParams(&$aEntitiesData)
    {
        foreach ($aEntitiesData as $entityId => $aEntity) {
            $linkparams = [];
            $params = $this->_removeDuplicateParams($aEntity['linkparams']);
            foreach ($params as $k => $v) {
                $linkparams[] = $k . '=' . urlencode($v);
            }
            if ($linkparams !== []) {
                $aEntitiesData[$entityId]['linkparams'] .= '&' . implode('&', $linkparams);
            }
        }
    }

    /**
     * Mask entities which have the hidden flag set
     *
     * @param array Entities array
     * @param string Name which should be used for hidden entitiies
     */
    public function maskHiddenEntities(&$aEntitiesData, $entityType)
    {
        $this->fixLinkParams($aEntitiesData);

        foreach (array_keys($aEntitiesData) as $entityId) {
            if (isset($aEntitiesData[$entityId]['hidden']) && $aEntitiesData[$entityId]['hidden']) {
                switch ($entityType) {
                    case 'advertiser':
                        $aEntitiesData[$entityId]['name'] = MAX_getAdvertiserName($aEntitiesData[$entityId]['name'], null, true, $aEntitiesData[$entityId]['id']);
                        break;

                    case 'campaign':
                        $tmp = [
                            'placement_id' => $aEntitiesData[$entityId]['id'],
                            'name' => $aEntitiesData[$entityId]['name'],
                            'anonymous' => true,
                        ];
                        $aEntitiesData[$entityId]['name'] = MAX_getPlacementName($tmp);
                        break;

                    case 'banner':
                        $aEntitiesData[$entityId]['name'] = MAX_getAdName($aEntitiesData[$entityId]['name'], null, null, true, $aEntitiesData[$entityId]['id']);
                        break;

                    case 'publisher':
                        $aEntitiesData[$entityId]['name'] = MAX_getPublisherName($aEntitiesData[$entityId]['name'], null, true, $aEntitiesData[$entityId]['id']);
                        break;

                    case 'zone':
                        $aEntitiesData[$entityId]['name'] = MAX_getZoneName($aEntitiesData[$entityId]['name'], null, true, $aEntitiesData[$entityId]['id']);
                        break;
                }

                //$aEntitiesData[$entityId]['num_children'] = 0;
                //unset($aEntitiesData[$entityId]['subentities']);
            }
        }

        if ($this->listOrderField == 'name' || $this->listOrderField == 'id') {
            MAX_sortArray(
                $aEntitiesData,
                $this->listOrderField,
                $this->listOrderDirection == 'up',
            );
        }
    }

    public function getAdvertisers($aParams, $level, $expand = '')
    {
        $aEntitiesData = parent::getAdvertisers($aParams, $level, $expand);

        $this->maskHiddenEntities($aEntitiesData, 'advertiser');

        return $aEntitiesData;
    }

    public function getCampaigns($aParams, $level, $expand = '')
    {
        $aEntitiesData = parent::getCampaigns($aParams, $level, $expand);

        $this->maskHiddenEntities($aEntitiesData, 'campaign');
        if ($level == $this->startLevel) {
            $this->addBlanks($aParams, $aEntitiesData);
        }

        return $aEntitiesData;
    }

    public function getBanners($aParams, $level, $expand = '')
    {
        $aEntitiesData = parent::getBanners($aParams, $level, $expand);

        $this->maskHiddenEntities($aEntitiesData, 'banner');
        if ($level == $this->startLevel) {
            $this->addBlanks($aParams, $aEntitiesData);
        }

        return $aEntitiesData;
    }

    public function getPublishers($aParams, $level, $expand = '')
    {
        $aEntitiesData = parent::getPublishers($aParams, $level, $expand);

        $this->maskHiddenEntities($aEntitiesData, 'publisher');
        if ($level == $this->startLevel) {
            $this->addDirectSelection($aParams, $aEntitiesData);
        }

        return $aEntitiesData;
    }

    public function getZones($aParams, $level, $expand = '')
    {
        $aEntitiesData = parent::getZones($aParams, $level, $expand);

        $this->maskHiddenEntities($aEntitiesData, 'zone');
        if ($level == $this->startLevel) {
            $this->addDirectSelection($aParams, $aEntitiesData);
        }

        return $aEntitiesData;
    }

    /**
     * Add direct selection stats to an entity array
     *
     * @param array Query parameters
     * @param array Entities array
     */
    public function addDirectSelection($aParams, &$aEntitiesData)
    {
        $aParams['exclude'] = ['ad_id'];
        $aParams['zone_id'] = 0;

        // Get plugin aParams
        $pluginParams = [];
        foreach ($this->aPlugins as $oPlugin) {
            $oPlugin->addQueryParams($pluginParams);
        }

        $aDirectSelection = Admin_DA::fromCache('getEntitiesStats', $aParams + $this->aDates);

        // Merge plugin additional data
        foreach ($this->aPlugins as $oPlugin) {
            $oPlugin->mergeData($aDirectSelection, 'getEntitiesStats', $aParams + $this->aDates, $this->aEmptyRow);
        }

        if (count($aDirectSelection)) {
            $zone = current($aDirectSelection) + $this->aEmptyRow;
            $zone['active'] = $this->_hasActiveStats($zone);

            if ($zone['active']) {
                $this->_summarizeStats($zone);

                $zone['name'] = $GLOBALS['strGenerateBannercode'];
                $zone['prefix'] = 'x';
                $zone['id'] = '-';
                $zone['icon'] = OX::assetPath() . '/images/icon-generatecode.gif';
                $zone['htmlclass'] = 'last';

                if ($this->listOrderField != 'name' && $this->listOrderField != 'id') {
                    $aEntitiesData[] = $zone;
                    MAX_sortArray(
                        $aEntitiesData,
                        $this->listOrderField,
                        $this->listOrderDirection == 'up',
                    );
                } elseif ($this->listOrderDirection == 'up') {
                    $aEntitiesData[] = $zone;
                } else {
                    array_unshift($aEntitiesData, $zone);
                }
            }
        }
    }

    /**
     * Add "blanks" stats to an entity array
     *
     * @param array Query parameters
     * @param array Entities array
     */
    public function addBlanks($aParams, &$aEntitiesData)
    {
        $aParams['exclude'] = ['zone_id'];
        $aParams['ad_id'] = 0;

        // Get plugin aParams
        $pluginParams = [];
        foreach ($this->aPlugins as $oPlugin) {
            $oPlugin->addQueryParams($pluginParams);
        }

        $aBlanks = Admin_DA::fromCache('getEntitiesStats', $aParams + $this->aDates, 1);

        // Merge plugin additional data
        foreach ($this->aPlugins as $oPlugin) {
            $oPlugin->mergeData($aBlanks, 'getEntitiesStats', $aParams + $this->aDates, $this->aEmptyRow);
        }

        if (count($aBlanks)) {
            $zone = current($aBlanks) + $this->aEmptyRow;
            $zone['active'] = $this->_hasActiveStats($zone);

            if ($zone['active']) {
                $this->_summarizeStats($zone);

                $zone['name'] = 'Blank impressions';
                $zone['prefix'] = 'x';
                $zone['id'] = '-';
                $zone['icon'] = OX::assetPath() . '/images/icon-banner-disabled.png';
                $zone['htmlclass'] = 'last';

                if ($this->listOrderField != 'name' && $this->listOrderField != 'id') {
                    $aEntitiesData[] = $zone;
                    MAX_sortArray(
                        $aEntitiesData,
                        $this->listOrderField,
                        $this->listOrderDirection == 'up',
                    );
                } elseif ($this->listOrderDirection == 'up') {
                    $aEntitiesData[] = $zone;
                } else {
                    array_unshift($aEntitiesData, $zone);
                }
            }
        }
    }
}
