<?php

/*
+---------------------------------------------------------------------------+
| Openads v2.3                                                              |
| ============                                                              |
|                                                                           |
| Copyright (c) 2003-2007 Openads Limited                                   |
| For contact details, see: http://www.openads.org/                         |
|                                                                           |
| This program is free software; you can redistribute it and/or modify      |
| it under the terms of the GNU General Public License as published by      |
| the Free Software Foundation; either version 2 of the License, or         |
| (at your option) any later version.                                       |
|                                                                           |
| This program is distributed in the hope that it will be useful,           |
| but WITHOUT ANY WARRANTY; without even the implied warranty of            |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             |
| GNU General Public License for more details.                              |
|                                                                           |
| You should have received a copy of the GNU General Public License         |
| along with this program; if not, write to the Free Software               |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA |
+---------------------------------------------------------------------------+
$Id: Region.plugin.php 8080 2007-07-10 17:29:19Z chris.nutting@openads.org $
*/

require_once MAX_PATH . '/plugins/deliveryLimitations/DeliveryLimitationsCommaSeparatedData.php';

/**
 * A Geo delivery limitation plugin, for filtering delivery of ads on the
 * basis of the viewer's country and region.
 *
 * Works with:
 * A string of format "CC|list" where "CC" is a valid country code and "list"
 * is a comma separated list of valid region codes. See the Region.res.inc.php
 * resource file for details of the valid country and region codes that can be
 * used with this plugin. (Note that the Country.res.inc.php resource file
 * contains a DIFFERENT list of valid country codes.)
 *
 * Valid comparison operators:
 * ==, !=
 *
 * @package    MaxPlugin
 * @subpackage DeliveryLimitations
 * @author     Andrew Hill <andrew@m3.net>
 * @author     Chris Nutting <chris@m3.net>
 *
 * @TODO Does this need to be updated to use =~ and !~ comparison operators?
 */
class Plugins_DeliveryLimitations_Geo_Region extends Plugins_DeliveryLimitations_CommaSeparatedData
{

    function init($data)
    {
        parent::init($data);
        if (is_array($this->data)) {
            $this->data = $this->_flattenData($this->data);
        }
    }


    /**
     * Return name of plugin
     *
     * @return string
     */
    function getName()
    {
        return MAX_Plugin_Translation::translate('Country / Region', $this->module, $this->package);
    }

    /**
     * Return if this plugin is available in the current context
     *
     * @return boolean
     */
    function isAllowed()
    {
        return isset($GLOBALS['_MAX']['GEO_DATA']['region'])
            || $GLOBALS['_MAX']['CONF']['geotargeting']['showUnavailable'];
    }

    /**
     * Outputs the HTML to display the data for this limitation
     *
     * @return void
     */
    function displayData()
    {
        $this->data = $this->_expandData($this->data);
        $tabindex =& $GLOBALS['tabindex'];

        // The region plugin is slightly different since we need to allow for multiple regions in different countries
        echo "
            <table border='0' cellpadding='2'>
                <tr>
                    <th>" . MAX_Plugin_Translation::translate('Country', $this->module, $this->package) . "</th>
                    <td>
                        <select name='acl[{$this->executionorder}][data][]' {$disabled}>";
                        foreach ($this->res as $countryCode => $countryName) {
                            if (count($countryName) === 1) { continue; }
                            $selected = ($this->data[0] == $countryCode) ? 'selected="selected"' : '';
                            echo "<option value='{$countryCode}' {$selected}>{$countryName[0]}</option>";
                        }
                        echo "
                        </select>
                    &nbsp;<input type='image' name='action[none]' src='images/{$GLOBALS['phpAds_TextDirection']}/go_blue.gif' border='0' align='absmiddle' alt='{$GLOBALS['strSave']}'></td>
                </tr>";

        if (!empty($this->data[0])) {
            // A country has been selected, show city list for this country...
            // Note: Since a disabled field does not pass it's value through, we need to pass the selected country in...
            echo "<tr><th>" . MAX_Plugin_Translation::translate('Region(s)', $this->module, $this->package) . "</th><td><div class='box'>";
            $aRegions = $this->res[$this->data[0]];
            unset($aRegions[0]);
            $aSelectedRegions = $this->data;
            unset ($aSelectedRegions[0]);
            foreach ($aRegions as $sCode => $sName) {
                echo "<div class='boxrow'>";
                echo "<input tabindex='".($tabindex++)."' ";
                echo "type='checkbox' id='c_{$this->executionorder}_{$sCode}' name='acl[{$this->executionorder}][data][]' value='{$sCode}'".(in_array($sCode, $aSelectedRegions) ? ' CHECKED' : '').">{$sName}</div>";
            }
            echo "</div></td></tr>";
        }
        echo "
            </table>
        ";
        $this->data = $this->_flattenData($this->data);
    }

    /**
     * A private method to "flatten" a delivery limitation into the string format that is
     * saved to the database (either in the acls, acls_channel or banners table, when part
     * of a compiled limitation string).
     *
     * Flattens the country and region array into string format.
     *
     * @access private
     * @param mixed $data An optional, expanded form delivery limitation.
     * @return string The delivery limitation in flattened format.
     */
    function _flattenData($data = null)
    {
        if (is_null($data)) {
            $data = $this->data;
        }
        if (is_array($data)) {
            $country = $data[0];
            unset($data[0]);
            return $country . '|' . implode(',', $data);

        }
        return $data;
    }

    /**
     * A private method to "expand" a delivery limitation from the string format that
     * is saved in the database (ie. in the acls or acls_channel table) into its
     * "expanded" form.
     *
     * Expands the string format into an array with the country code in the first
     * element, and the region codes in the remaining elements.
     *
     * @access private
     * @param string $data An optional, flat form delivery limitation data string.
     * @return mixed The delivery limitation data in expanded format.
     */
    function _expandData($data = null)
    {
        if (is_null($data)) {
            $data = $this->data;
        }
        if (!is_array($data)) {
            $aData = strlen($data) ? explode('|', $data) : array();
            $aRegions = MAX_limitationsGetAFromS($aData[1]);
            return array_merge(array($aData[0]), $aRegions);
        }
        return $data;
    }

    function compile()
    {
        return $this->compileData($this->_preCompile($this->data));
    }

    function _preCompile($sData)
    {
        $aData = $this->_expandData($sData);
        $aData = MAX_limitationsGetPreprocessedArray($aData);
        return $this->_flattenData($aData);
    }

    /**
     * A private method to return this delivery limitation plugin as a SQL limiation.
     *
     * @access private
     * @param string $comparison As for Plugins_DeliveryLimitations::_getSqlLimitation(),
     *                           but only '=' and '!=' permitted.
     * @param string $data A pipe (|) separated list of two items - firstly, a country
     *                     code, and secondly, a comma separated list of region codes.
     * @return mixed As for Plugins_DeliveryLimitations::_getSqlLimitation().
     */
    function _getSqlLimitation($comparison, $data)
    {
        $sData = $this->_preCompile($data);
        $aData = $this->_expandData($sData);
        $sCountry = $aData[0];
        unset($aData[0]);
        $queryCountry = MAX_limitationsGetSqlForString('==', $sCountry, 'country');
        $queryRegion = MAX_limitationsGetSqlForArray('=~', $aData, 'geo_region');
        return "($queryCountry AND $queryRegion)";
    }

    /**
     * A method to compare two comparison and data groups of the same delivery
     * limitation type, and determine if the delivery limitations have any
     * overlap, or not.
     *
     * @param array $aLimitation1 An array containing the "comparison" and "data"
     *                            fields of the first delivery limitation.
     * @param array $aLimitation2 An array containing the "comparison" and "data"
     *                            fields of the second delivery limitation.
     * @return boolean True if there is overlap between the two delivery limitations,
     *                 false if there is NOT any overlap.
     */
    function overlap($aLimitation1, $aLimitation2)
    {
        $aData1 = $this->_expandData($aLimitation1['data']);
        $aData2 = $this->_expandData($aLimitation2['data']);

        $sCountry1 = MAX_limitationsGetCountry($aData1);
        $sCountry2 = MAX_limitationsGetCountry($aData2);

        if ($sCountry1 != $sCountry2) {
            return false;
        }
        unset($aData1[0]);
        unset($aData2[0]);

        $aData1 = MAX_limitationsGetPreprocessedArray($aData1);
        $aData2 = MAX_limitationsGetPreprocessedArray($aData2);

        return MAX_limitationsDoArraysOverlap($aData1, $aData2);
    }

    /**
     * A method to upgrade the Geo:Region delivery limitation plugin from v0.3.29-alpha
     * to v0.3.31-alpha format.
     *
     * @param string $op The comparison string for the limitation in v0.3.29-alpha format.
     * @param string $sData The comparison data for the limitation in v0.3.29-alpha format.
     * @return array An array of two items, indexed by "op" and "data", which are the new
     *               v0.3.31-alpha format versions of the parameters above.
     */
    function getDeliveryLimitationPluginUpgradeThreeThirtyOneAlpha($op, $sData)
    {
        return array('op' => $op, 'data' => $sData);
    }

    /**
     * A method to downgrade the Geo:Region delivery limitation plugin from v0.3.29-alpha
     * to v0.3.31-alpha format.
     *
     * @param string $op The comparison string for the limitation in v0.3.31-alpha format.
     * @param string $sData The comparison data for the limitation in v0.3.31-alpha format.
     * @return array An array of two items, indexed by "op" and "data", which are the old
     *               v0.3.29-alpha format versions of the parameters above.
     */
    function getDeliveryLimitationPluginDowngradeThreeTwentyNineAlpha($op, $sData)
    {
        return array('op' => $op, 'data' => $sData);
    }


    function getUpgradeFromEarly($op, $sData)
    {
        return OA_limitationsGetUpgradeForGeoRegion($op, $sData);
    }

}

?>
