      1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272:

    <?php

    namespace WPGMZA;

    $dir = preg_replace('/wp-google-maps-pro/', 'wp-google-maps', __DIR__);

    require_once(plugin_dir_path($dir) . 'includes/class.factory.php');
    require_once(plugin_dir_path($dir) . 'includes/class.marker-filter.php');

    class ProMarkerFilter extends MarkerFilter
    {
        protected $_keywords;
        protected $_categories;
        protected $_map_id;
        protected $_mashupIDs;
        protected $_customFields;
        protected $_includeUnapproved;

        public function __construct($options=null)
        {
            MarkerFilter::__construct($options);
        }

        public function __get($name)
        {
            if(property_exists($this, "_$name"))
                return $this->{"_$name"};

            return $this->{$name};
        }

        public function __set($name, $value)
        {
            MarkerFilter::__set($name, $value);

            switch($name)
            {
                case "map_id":
                    $this->loadMap();
                    break;

                case "includeUnapproved":
                    if(!current_user_can('administrator'))
                        throw new \Exception('Permission denied');
                    break;
            }
        }

        protected function loadMap()
        {
            $this->map = new Map($this->_map_id);
        }

        protected function applyKeywordsClause($query)
        {
            global $wpdb;

            if(!$this->_keywords)
                return;

            $keywords = '%' . $wpdb->esc_like("{$this->_keywords}") . '%';

            $query->where['keywords'] = "
                (
                    title LIKE %s
                    OR
                    description LIKE %s
                    OR
                    address LIKE %s
                )
            ";

            $query->params[] = $keywords;
            $query->params[] = $keywords;
            $query->params[] = $keywords;
        }

        protected function applyMapIDClause($query)
        {
            if(!empty($this->_mashupIDs))
            {
                $ids = array_merge($this->_mashupIDs);

                if(!empty($this->_map_id))
                    $ids[] = $this->_map_id;

                $placeholders = implode(',', array_fill(0, count($ids), "%d"));

                $query->where['mashup_ids'] = "map_id IN ($placeholders)";

                foreach($ids as $id)
                    $query->params[] = $id;

                return;
            }

            if(!empty($this->_map_id))
            {
                $query->where['map_id'] = 'map_id = %d';
                $query->params[] = $this->_map_id;
            }
        }

        protected function applyApprovedClause($query)
        {
            if($this->_includeUnapproved)
                return;

            $query->where['approved'] = 'approved = 1';
        }

        /*protected function applyKeywordsClause($query)
        {
            global $wpdb;
            global $mapBlockPlugin;

            if(!ProMarkerFilter::$cachedSearchableColumnsByTableName)
                ProMarkerFilter::$cachedSearchableColumnsByTableName = array();

            $tableName = $this->getTableName();

            if(!isset(ProMarkerFilter::$cachedSearchableColumnsByTableName[$tableName]))
            {
                ProMarkerFilter::$cachedSearchableColumnsByTableName[$tableName] = array();

                $columns = $wpdb->get_results("SHOW COLUMNS FROM $tableName");

                foreach($columns as $col)
                {
                    if(preg_match('/varchar|text/i', $col->Type))
                        ProMarkerFilter::$cachedSearchableColumnsByTableName[$tableName][] = $col->Field;
                }
            }

            $keywords = $this->keywords;

            if(empty($keywords))
                return;

            $operator = "LIKE";

            if($this->_map->keyword_filter_enable_regular_expressions)
            {
                // Only allow the REGEXP operator if keywords is a valid regular expression
                if(preg_match($keywords, null) !== false)
                    $operator = "REGEXP";
            }

            $columns = ProMarkerFilter::$cachedSearchableColumnsByTableName[$tableName];
            $columns = array_map(function($input) {
                return "`$input` LIKE %s";
            }, $columns);

            $like = '%' . $wpdb->esc_like("{$keywords}") . '%';

            $query->where['keywords'] = "
                (
                    " . implode(' OR ', $columns) . "
                )
            ";

            for($i = 0; $i < count($columns); $i++)
                $query->params[] = $like;
        }*/

        protected function applyCategoriesClause($query)
        {
            global $wpdb;
            global $wpgmza;

            $hasTableName   = $wpdb->prefix . "wpgmza_markers_has_categories";
            $categories     = $this->categories;

            if(empty($categories))
                return;

            if(is_int($categories))
                $categories = array($categories);

            $placeholders   = implode(',', array_fill(0, count($categories), '%d'));

            if(empty($categories))
                return;

            switch($wpgmza->settings->wpgmza_settings_cat_logic)
            {
                case "1":
                    $operator = "AND";
                    break;

                default:
                    $operator = "OR";
                    break;
            }

            $categoryTree = new CategoryTree();
            $categoryIDs = array();

            foreach($categories as $category)
            {
                $categoryIDs[] = $category;

                $node = $categoryTree->getChildByID($category);

                if(!$node)
                    continue;

                foreach($node->getDescendants() as $descendant)
                    $categoryIDs[] = $descendant->id;
            }

            $imploded = implode(',', array_unique($categoryIDs));

            $queries = array();

            for($i = 0; $i < count($categoryIDs); $i++)
            {
                $queries[] = "
                    id IN
                    (
                        SELECT marker_id
                        FROM {$wpdb->prefix}wpgmza_markers_has_categories
                        WHERE category_id = %d
                    )
                ";

                $query->params[] = $categoryIDs[$i];
            }

            $query->where['categories'] = "(" . implode(" $operator ", $queries) . ")";
        }

        protected function applyCustomFieldClause($query)
        {
            if(empty($this->_customFields))
                return;

            // TODO: This will not work for mashups
            $controller = apply_filters('wpgmza_get_custom_field_filter_controlller', array(
                'map_id'        => $this->_map_id,
                'widgetData'    => $this->_customFields
            ));

            $markerIDs = $controller->getFilteredMarkerIDs();
            $imploded = implode(', ', array_map('intval', $markerIDs));

            if(empty($markerIDs))
                $query->where['custom_fields'] = '0';
            else
                $query->where['custom_fields'] = "(id IN ($imploded))";
        }

        public function getQuery()
        {
            $query = MarkerFilter::getQuery();

            $this->applyMapIDClause($query);
            $this->applyApprovedClause($query);
            $this->applyKeywordsClause($query);
            $this->applyCategoriesClause($query);
            $this->applyCustomFieldClause($query);

            return $query;
        }
    }

    add_filter('wpgmza_create_WPGMZA\\MarkerFilter', function($options) {

        return new ProMarkerFilter($options);

    }, 10, 1);