* SPDX-License-Identifier: AGPL-3.0-only ************************************/ /* crmv@198038 */ include_once('vtlib/Vtecrm/Utils.php'); include_once('vtlib/Vtecrm/Version.php'); /** * Provides API to work with CRM Custom View (Filter) * @package vtlib */ class Vtecrm_Filter { /** ID of this filter instance */ var $id; var $name; var $isdefault; var $status = false; // 5.1.0 onwards var $inmetrics = false; var $inmobile = false; // crmv@49398 var $entitytype= false; var $module; /** * Constructor */ function __construct() { } /** * Get unique id for this instance * @access private */ function __getUniqueId() { global $adb,$table_prefix; return $adb->getUniqueID($table_prefix.'_customview'); } /** * Initialize this filter instance * @param Vtecrm_Module Instance of the module to which this filter is associated. * @access private */ function initialize($valuemap, $moduleInstance=false) { $this->id = $valuemap['cvid']; $this->name= $valuemap['viewname']; $this->module=$moduleInstance? $moduleInstance: Vtecrm_Module::getInstance($valuemap['tabid']); } // crmv@49398 /** * Create this instance * @param Vtecrm_Module Instance of the module to which this filter should be associated with * @access private */ function __create($moduleInstance) { global $adb,$table_prefix, $metaLogs; $this->module = $moduleInstance; $this->id = $this->__getUniqueId(); $this->isdefault = ($this->isdefault===true||$this->isdefault=='true')?1:0; $this->inmetrics = ($this->inmetrics===true||$this->inmetrics=='true')?1:0; $this->inmobile = ($this->inmobile===true||$this->inmobile=='true')?1:0; $adb->pquery("INSERT INTO ".$table_prefix."_customview(cvid,viewname,setdefault,setmetrics,setmobile,entitytype) VALUES(?,?,?,?,?,?)", Array($this->id, $this->name, $this->isdefault, $this->inmetrics, $this->inmobile, $this->module->name)); if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_ADDFILTER, $this->id); self::log("Creating Filter $this->name ... DONE"); // Filters are role based from 5.1.0 onwards if(!$this->status) { if(strtoupper(trim($this->name)) == 'ALL') $this->status = '0'; // Default else $this->status = '3'; // Public $adb->pquery("UPDATE ".$table_prefix."_customview SET status=? WHERE cvid=?", Array($this->status, $this->id)); self::log("Setting Filter $this->name to status [$this->status] ... DONE"); } // END } // crmv@49398e /** * Update this instance * @access private * @internal TODO */ function __update() { self::log("Updating Filter $this->name ... DONE"); } /** * Delete this instance * @access private */ function __delete() { global $adb,$table_prefix, $metaLogs; // crmv@49398 $adb->pquery("DELETE FROM ".$table_prefix."_cvadvfilter WHERE cvid=?", Array($this->id)); $adb->pquery("DELETE FROM ".$table_prefix."_cvcolumnlist WHERE cvid=?", Array($this->id)); $adb->pquery("DELETE FROM ".$table_prefix."_customview WHERE cvid=?", Array($this->id)); if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_DELFILTER, $this->id, array('module'=>$this->module->name)); // crmv@49398 } /** * Save this instance * @param Vtecrm_Module Instance of the module to use */ function save($moduleInstance=false) { if($this->id) $this->__update(); else $this->__create($moduleInstance); return $this->id; } /** * Delete this instance * @access private */ function delete() { $this->__delete(); } /** * Get the column value to use in custom view tables. * @param Vtecrm_Field Instance of the field * @access private */ function __getColumnValue($fieldInstance) { $tod = explode('~', $fieldInstance->typeofdata); $displayinfo = $fieldInstance->getModuleName().'_'.str_replace(' ','_',$fieldInstance->label).':'.$tod[0]; $cvcolvalue = "$fieldInstance->table:$fieldInstance->column:$fieldInstance->name:$displayinfo"; return $cvcolvalue; } /** * Add the field to this filer instance * @param Vtecrm_Field Instance of the field * @param Integer Index count to use */ function addField($fieldInstance, $index=0) { global $adb,$table_prefix, $metaLogs; // crmv@49398 $cvcolvalue = $this->__getColumnValue($fieldInstance); // crmv@63472 $res = $adb->pquery("SELECT MAX(columnindex) AS maxcolumnindex FROM {$table_prefix}_cvcolumnlist WHERE cvid = ?", array($this->id)); if ($res && $adb->num_rows($res) > 0) { $row = $adb->fetchByAssoc($res, -1, false); $maxColumnIndex = intval($row["maxcolumnindex"]); } else { $maxColumnIndex = -1; } while ($maxColumnIndex >= $index) { $adb->pquery("UPDATE ".$table_prefix."_cvcolumnlist SET columnindex = columnindex+1 WHERE cvid=? AND columnindex=?", Array($this->id, $maxColumnIndex)); $maxColumnIndex--; } // crmv@63472e $adb->pquery("INSERT INTO ".$table_prefix."_cvcolumnlist(cvid,columnindex,columnname) VALUES(?,?,?)", Array($this->id, $index, $cvcolvalue)); if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_EDITFILTER, $this->id); // crmv@49398 $this->log("Adding $fieldInstance->name to $this->name filter ... DONE"); return $this; } /* * remove field from the columnlist (and from filters if 2nd param = true) */ function removeField($fieldInstance, $from_filters = false) { global $adb,$table_prefix, $metaLogs; // crmv@49398 $cvcolvalue = $this->__getColumnValue($fieldInstance); // get field index $res = $adb->pquery("SELECT columnindex as idx FROM ".$table_prefix."_cvcolumnlist WHERE cvid=? AND columnname=?", Array($this->id, $cvcolvalue)); if ($res && $adb->num_rows($res) > 0) { // get index $index = $adb->query_result($res, 0, 'idx'); // remove field $adb->pquery("DELETE FROM ".$table_prefix."_cvcolumnlist WHERE cvid=? AND columnname=?", Array($this->id, $cvcolvalue)); if ($from_filters) { $adb->pquery("DELETE FROM ".$table_prefix."_cvadvfilter WHERE cvid=? AND columnname=?", Array($this->id, $cvcolvalue)); $adb->pquery("DELETE FROM ".$table_prefix."_cvstdfilter WHERE cvid=? AND columnname=?", Array($this->id, $cvcolvalue)); } // reorder indexes if ($index != '') { $adb->pquery("UPDATE ".$table_prefix."_cvcolumnlist SET columnindex=columnindex-1 WHERE cvid=? AND columnindex>?",Array($this->id, $index)); } } if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_EDITFILTER, $this->id); // crmv@49398 $this->log("Removing $fieldInstance->name to $this->name filter ... DONE"); return $this; } /** * Add rule to this filter instance * @param Vtecrm_Field Instance of the field * @param String One of [EQUALS, NOT_EQUALS, STARTS_WITH, ENDS_WITH, CONTAINS, DOES_NOT_CONTAINS, LESS_THAN, * GREATER_THAN, LESS_OR_EQUAL, GREATER_OR_EQUAL] * @param String Value to use for comparision * @param Integer Index count to use */ function addRule($fieldInstance, $comparator, $comparevalue, $index=0) { global $adb,$table_prefix, $metaLogs; // crmv@49398 if(empty($comparator)) return $this; $comparator = self::translateComparator($comparator); $cvcolvalue = $this->__getColumnValue($fieldInstance); $adb->pquery("UPDATE ".$table_prefix."_cvadvfilter set columnindex=columnindex+1 WHERE cvid=? AND columnindex>=?", Array($this->id, $index)); $adb->pquery("INSERT INTO ".$table_prefix."_cvadvfilter(cvid, columnindex, columnname, comparator, value) VALUES(?,?,?,?,?)", Array($this->id, $index, $cvcolvalue, $comparator, $comparevalue)); if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_EDITFILTER, $this->id); // crmv@49398 Vtecrm_Utils::Log("Adding Condition " . self::translateComparator($comparator,true) ." on $fieldInstance->name of $this->name filter ... DONE"); return $this; } //crmv@26370 /** * Add standard rule to this filter instance * @param Vtecrm_Field Instance of the field * @param String One of [custom ,prevfy, thisfy, nextfy, prevfq, thisfq, nextfq, yesterday, today, * tomorrow, lastweek, thisweek, nextweek, lastmonth, thismonth, nextmonth, * last7days, last30days, last60days, last90days, last120days, next30days, * next60days, next90days, next120days] * @param String Start Date in case $duration is "custom" * @param String End Date in case $duration is "custom" * @param Bool Consider only month and day * TODO: do update if exists, check if field is a date field */ function addStandardRule($fieldInstance, $duration, $date_start = null, $date_end = null, $only_month= false) { global $adb,$table_prefix, $metaLogs; // crmv@49398 $valid_durations = array( "custom", "prevfy", "thisfy", "nextfy", "prevfq", "thisfq", "nextfq", "yesterday", "today", "tomorrow", "lastweek", "thisweek", "nextweek", "lastmonth", "thismonth", "nextmonth", "last7days", "last30days", "last60days", "last90days", "last120days", "next30days", "next60days", "next90days", "next120days" ); if(empty($duration)) return $this; if (!in_array($duration, $valid_durations)) { Vtecrm_Utils::log("Error adding standard condition, unknown duration : $duration"); return $this; } if ($duration == 'custom' && (empty($date_start) || empty($date_end))) { Vtecrm_Utils::log("Error adding standard condition, dates cannot be null in custom mode"); return $this; } $cvcolvalue = $this->__getColumnValue($fieldInstance); // remove type $cols = explode(':', $cvcolvalue); if (strlen(end($cols)) == 1) { reset($cols); array_pop($cols); $cvcolvalue = implode(':', $cols); } $params = array($this->id, $cvcolvalue, $duration, $date_start, $date_end, intval($only_month)); $res = $adb->pquery("INSERT INTO ".$table_prefix."_cvstdfilter(cvid, columnname, stdfilter, startdate, enddate, only_month_and_day) VALUES(?,?,?,?,?,?)", $params); if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_EDITFILTER, $this->id); // crmv@49398 Vtecrm_Utils::Log("Adding Standard Condition $duration on {$fieldInstance->name} of {$this->name} filter ... DONE"); return $this; } //crmv@26370e /** * Translate comparator (condition) to long or short form. * @access private * @internal Used from Vtecrm_PackageExport also */ static function translateComparator($value, $tolongform=false) { $comparator = false; if($tolongform) { $comparator = strtolower($value); if($comparator == 'e') $comparator = 'EQUALS'; else if($comparator == 'n') $comparator = 'NOT_EQUALS'; else if($comparator == 's') $comparator = 'STARTS_WITH'; else if($comparator == 'ew') $comparator = 'ENDS_WITH'; else if($comparator == 'c') $comparator = 'CONTAINS'; else if($comparator == 'k') $comparator = 'DOES_NOT_CONTAINS'; else if($comparator == 'l') $comparator = 'LESS_THAN'; else if($comparator == 'g') $comparator = 'GREATER_THAN'; else if($comparator == 'm') $comparator = 'LESS_OR_EQUAL'; else if($comparator == 'h') $comparator = 'GREATER_OR_EQUAL'; } else { $comparator = strtoupper($value); if($comparator == 'EQUALS') $comparator = 'e'; else if($comparator == 'NOT_EQUALS') $comparator = 'n'; else if($comparator == 'STARTS_WITH') $comparator = 's'; else if($comparator == 'ENDS_WITH') $comparator = 'ew'; else if($comparator == 'CONTAINS') $comparator = 'c'; else if($comparator == 'DOES_NOT_CONTAINS') $comparator = 'k'; else if($comparator == 'LESS_THAN') $comparator = 'l'; else if($comparator == 'GREATER_THAN') $comparator = 'g'; else if($comparator == 'LESS_OR_EQUAL') $comparator = 'm'; else if($comparator == 'GREATER_OR_EQUAL') $comparator = 'h'; } return $comparator; } /** * Helper function to log messages * @param String Message to log * @param Boolean true appends linebreak, false to avoid it * @access private */ static function log($message, $delim=true) { Vtecrm_Utils::Log($message, $delim); } /** * Get instance by filterid or filtername * @param mixed filterid or filtername * @param Vtecrm_Module Instance of the module to use when filtername is used */ static function getInstance($value, $moduleInstance=false) { global $adb,$table_prefix; $instance = false; $query = false; $queryParams = false; if(Vtecrm_Utils::isNumber($value)) { $query = "SELECT * FROM ".$table_prefix."_customview WHERE cvid=?"; $queryParams = Array($value); } else { $query = "SELECT * FROM ".$table_prefix."_customview WHERE viewname=? AND entitytype=?"; $queryParams = Array($value, $moduleInstance->name); } $result = $adb->pquery($query, $queryParams); if($adb->num_rows($result)) { $class = get_called_class() ?: get_class(); $instance = new $class(); $instance->initialize($adb->fetch_array($result), $moduleInstance); } return $instance; } /** * Get all instances of filter for the module * @param Vtecrm_Module Instance of module */ static function getAllForModule($moduleInstance) { global $adb,$table_prefix; $instances = false; $query = "SELECT * FROM ".$table_prefix."_customview WHERE entitytype=?"; $queryParams = Array($moduleInstance->name); $result = $adb->pquery($query, $queryParams); for($index = 0; $index < $adb->num_rows($result); ++$index) { $class = get_called_class() ?: get_class(); $instance = new $class(); $instance->initialize($adb->fetch_array($result), $moduleInstance); $instances[] = $instance; } return $instances; } /** * Delete filter associated for module * @param Vtecrm_Module Instance of module */ static function deleteForModule($moduleInstance) { global $adb,$table_prefix, $metaLogs; // crmv@49398 $cvidres = $adb->pquery("SELECT cvid FROM ".$table_prefix."_customview WHERE entitytype=?", Array($moduleInstance->name)); if($adb->num_rows($cvidres)) { $cvids = Array(); for($index = 0; $index < $adb->num_rows($cvidres); ++$index) { $cvids[] = $adb->query_result($cvidres, $index, 'cvid'); } if(!empty($cvids)) { $adb->query("DELETE FROM ".$table_prefix."_cvadvfilter WHERE cvid IN (" . implode(',', $cvids) . ")"); $adb->query("DELETE FROM ".$table_prefix."_cvcolumnlist WHERE cvid IN (" . implode(',', $cvids) . ")"); $adb->query("DELETE FROM ".$table_prefix."_customview WHERE cvid IN (" . implode(',', $cvids) . ")"); if ($metaLogs) $metaLogs->log($metaLogs::OPERATION_EDITMODFILTERS, 0, array('module'=>$moduleInstance->name)); // crmv@49398 } } } }