function vtws_sync($mtime, $elementType, $syncType, $user)
{
    global $adb, $recordString, $modifiedTimeString;
    $numRecordsLimit = 100;
    $ignoreModules = array("Users");
    $typed = true;
    $dformat = "Y-m-d H:i:s";
    $datetime = date($dformat, $mtime);
    $setypeArray = array();
    $setypeData = array();
    $setypeHandler = array();
    $setypeNoAccessArray = array();
    $output = array();
    $output["updated"] = array();
    $output["deleted"] = array();
    $applicationSync = false;
    if (is_object($syncType) && $syncType instanceof Users) {
        $user = $syncType;
    } else {
        if ($syncType == 'application') {
            $applicationSync = true;
        } else {
            if ($syncType == 'userandgroup') {
                $userAndGroupSync = true;
            }
        }
    }
    if ($applicationSync && !is_admin($user)) {
        throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Only admin users can perform application sync");
    }
    $ownerIds = array($user->id);
    // To get groupids in which this user exist
    if ($userAndGroupSync) {
        $groupresult = $adb->pquery("select groupid from vtiger_users2group where userid=?", array($user->id));
        $numOfRows = $adb->num_rows($groupresult);
        if ($numOfRows > 0) {
            for ($i = 0; $i < $numOfRows; $i++) {
                $ownerIds[count($ownerIds)] = $adb->query_result($groupresult, $i, "groupid");
            }
        }
    }
    // End
    if (!isset($elementType) || $elementType == '' || $elementType == null) {
        $typed = false;
    }
    $adb->startTransaction();
    $accessableModules = array();
    $entityModules = array();
    $modulesDetails = vtws_listtypes(null, $user);
    $moduleTypes = $modulesDetails['types'];
    $modulesInformation = $modulesDetails["information"];
    foreach ($modulesInformation as $moduleName => $entityInformation) {
        if ($entityInformation["isEntity"]) {
            $entityModules[] = $moduleName;
        }
    }
    if (!$typed) {
        $accessableModules = $entityModules;
    } else {
        if (!in_array($elementType, $entityModules)) {
            throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to perform the operation is denied");
        }
        $accessableModules[] = $elementType;
    }
    $accessableModules = array_diff($accessableModules, $ignoreModules);
    if (count($accessableModules) <= 0) {
        $output['lastModifiedTime'] = $mtime;
        $output['more'] = false;
        return $output;
    }
    if ($typed) {
        $handler = vtws_getModuleHandlerFromName($elementType, $user);
        $moduleMeta = $handler->getMeta();
        $entityDefaultBaseTables = $moduleMeta->getEntityDefaultTableList();
        //since there will be only one base table for all entities
        $baseCRMTable = $entityDefaultBaseTables[0];
        if ($elementType == "Calendar" || $elementType == "Events") {
            $baseCRMTable = getSyncQueryBaseTable($elementType);
        }
    } else {
        $baseCRMTable = " vtiger_crmentity ";
    }
    //modifiedtime - next token
    $q = "SELECT modifiedtime FROM {$baseCRMTable} WHERE  modifiedtime>? and setype IN(" . generateQuestionMarks($accessableModules) . ") ";
    $params = array($datetime);
    foreach ($accessableModules as $entityModule) {
        if ($entityModule == "Events") {
            $entityModule = "Calendar";
        }
        $params[] = $entityModule;
    }
    if (!$applicationSync) {
        $q .= ' and smownerid IN(' . generateQuestionMarks($ownerIds) . ')';
        $params = array_merge($params, $ownerIds);
    }
    $q .= " order by modifiedtime limit {$numRecordsLimit}";
    $result = $adb->pquery($q, $params);
    $modTime = array();
    for ($i = 0; $i < $adb->num_rows($result); $i++) {
        $modTime[] = $adb->query_result($result, $i, 'modifiedtime');
    }
    if (!empty($modTime)) {
        $maxModifiedTime = max($modTime);
    }
    if (!$maxModifiedTime) {
        $maxModifiedTime = $datetime;
    }
    foreach ($accessableModules as $elementType) {
        $handler = vtws_getModuleHandlerFromName($elementType, $user);
        $moduleMeta = $handler->getMeta();
        $deletedQueryCondition = $moduleMeta->getEntityDeletedQuery();
        preg_match_all("/(?:\\s+\\w+[ \t\n\r]+)?([^=]+)\\s*=([^\\s]+|'[^']+')/", $deletedQueryCondition, $deletedFieldDetails);
        $fieldNameDetails = $deletedFieldDetails[1];
        $deleteFieldValues = $deletedFieldDetails[2];
        $deleteColumnNames = array();
        foreach ($fieldNameDetails as $tableName_fieldName) {
            $fieldComp = explode(".", $tableName_fieldName);
            $deleteColumnNames[$tableName_fieldName] = $fieldComp[1];
        }
        $params = array($moduleMeta->getTabName(), $datetime, $maxModifiedTime);
        $queryGenerator = new QueryGenerator($elementType, $user);
        $fields = array();
        $moduleFields = $moduleMeta->getModuleFields();
        $moduleFieldNames = getSelectClauseFields($elementType, $moduleMeta, $user);
        $moduleFieldNames[] = 'id';
        $queryGenerator->setFields($moduleFieldNames);
        $selectClause = "SELECT " . $queryGenerator->getSelectClauseColumnSQL();
        // adding the fieldnames that are present in the delete condition to the select clause
        // since not all fields present in delete condition will be present in the fieldnames of the module
        foreach ($deleteColumnNames as $table_fieldName => $columnName) {
            if (!in_array($columnName, $moduleFieldNames)) {
                $selectClause .= ", " . $table_fieldName;
            }
        }
        if ($elementType == "Emails") {
            $fromClause = vtws_getEmailFromClause();
        } else {
            $fromClause = $queryGenerator->getFromClause();
        }
        $fromClause .= " INNER JOIN (select modifiedtime, crmid,deleted,setype FROM {$baseCRMTable} WHERE setype=? and modifiedtime >? and modifiedtime<=?";
        if (!$applicationSync) {
            $fromClause .= 'and smownerid IN(' . generateQuestionMarks($ownerIds) . ')';
            $params = array_merge($params, $ownerIds);
        }
        $fromClause .= ' ) vtiger_ws_sync ON (vtiger_crmentity.crmid = vtiger_ws_sync.crmid)';
        $q = $selectClause . " " . $fromClause;
        $result = $adb->pquery($q, $params);
        $recordDetails = array();
        $deleteRecordDetails = array();
        while ($arre = $adb->fetchByAssoc($result)) {
            $key = $arre[$moduleMeta->getIdColumn()];
            if (vtws_isRecordDeleted($arre, $deleteColumnNames, $deleteFieldValues)) {
                if (!$moduleMeta->hasAccess()) {
                    continue;
                }
                $output["deleted"][] = vtws_getId($moduleMeta->getEntityId(), $key);
            } else {
                if (!$moduleMeta->hasAccess() || !$moduleMeta->hasPermission(EntityMeta::$RETRIEVE, $key)) {
                    continue;
                }
                try {
                    $output["updated"][] = DataTransform::sanitizeDataWithColumn($arre, $moduleMeta);
                } catch (WebServiceException $e) {
                    //ignore records the user doesn't have access to.
                    continue;
                } catch (Exception $e) {
                    throw new WebServiceException(WebServiceErrorCode::$INTERNALERROR, "Unknown Error while processing request");
                }
            }
        }
    }
    $q = "SELECT crmid FROM {$baseCRMTable} WHERE modifiedtime>?  and setype IN(" . generateQuestionMarks($accessableModules) . ")";
    $params = array($maxModifiedTime);
    foreach ($accessableModules as $entityModule) {
        if ($entityModule == "Events") {
            $entityModule = "Calendar";
        }
        $params[] = $entityModule;
    }
    if (!$applicationSync) {
        $q .= 'and smownerid IN(' . generateQuestionMarks($ownerIds) . ')';
        $params = array_merge($params, $ownerIds);
    }
    $result = $adb->pquery($q, $params);
    if ($adb->num_rows($result) > 0) {
        $output['more'] = true;
    } else {
        $output['more'] = false;
    }
    if (!$maxModifiedTime) {
        $modifiedtime = $mtime;
    } else {
        $modifiedtime = vtws_getSeconds($maxModifiedTime);
    }
    if (is_string($modifiedtime)) {
        $modifiedtime = intval($modifiedtime);
    }
    $output['lastModifiedTime'] = $modifiedtime;
    $error = $adb->hasFailedTransaction();
    $adb->completeTransaction();
    if ($error) {
        throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR, vtws_getWebserviceTranslatedString('LBL_' . WebServiceErrorCode::$DATABASEQUERYERROR));
    }
    VTWS_PreserveGlobal::flush();
    return $output;
}
Beispiel #2
0
 /**
  * Get the list of changed record after $mtime
  * @param <type> $mtime
  * @param <type> $user
  * @param <type> $limit 
  */
 function getChangedRecords($uniqueId, $mtime, $limit = 100)
 {
     global $current_user, $adb;
     $datetime = date('Y-m-d H:i:s', $mtime);
     $accessibleModules = $this->getModTrackerEnabledModules();
     if (empty($accessibleModules)) {
         throw new Exception('Modtracker not enabled for any modules');
     }
     $query = "SELECT id, module, modifiedtime, vtiger_crmentity.crmid, smownerid, vtiger_modtracker_basic.status\n                FROM vtiger_modtracker_basic\n                INNER JOIN vtiger_crmentity ON vtiger_modtracker_basic.crmid = vtiger_crmentity.crmid\n                    AND vtiger_modtracker_basic.changedon = vtiger_crmentity.modifiedtime\n                WHERE id > ? AND changedon >= ? AND module IN(" . generateQuestionMarks($accessibleModules) . ")\n                ORDER BY id";
     $params = array($uniqueId, $datetime);
     foreach ($accessibleModules as $entityModule) {
         $params[] = $entityModule;
     }
     if ($limit != false) {
         $query .= " LIMIT {$limit}";
     }
     $result = $adb->pquery($query, $params);
     $modTime = array();
     $rows = $adb->num_rows($result);
     for ($i = 0; $i < $rows; $i++) {
         $status = $adb->query_result($result, $i, 'status');
         $record['uniqueid'] = $adb->query_result($result, $i, 'id');
         $record['modifiedtime'] = $adb->query_result($result, $i, 'modifiedtime');
         $record['module'] = $adb->query_result($result, $i, 'module');
         $record['crmid'] = $adb->query_result($result, $i, 'crmid');
         $record['assigneduserid'] = $adb->query_result($result, $i, 'smownerid');
         if ($status == ModTracker::$DELETED) {
             $deletedRecords[] = $record;
         } elseif ($status == ModTracker::$CREATED) {
             $createdRecords[] = $record;
         } elseif ($status == ModTracker::$UPDATED) {
             $updatedRecords[] = $record;
         }
         $modTime[] = $record['modifiedtime'];
         $uniqueIds[] = $record['uniqueid'];
     }
     if (!empty($uniqueIds)) {
         $maxUniqueId = max($uniqueIds);
     }
     if (empty($maxUniqueId)) {
         $maxUniqueId = $uniqueId;
     }
     if (!empty($modTime)) {
         $maxModifiedTime = max($modTime);
     }
     if (!$maxModifiedTime) {
         $maxModifiedTime = $datetime;
     }
     $output['created'] = $createdRecords;
     $output['updated'] = $updatedRecords;
     $output['deleted'] = $deletedRecords;
     $moreQuery = "SELECT * FROM vtiger_modtracker_basic WHERE id > ? AND changedon >= ? AND module\n            IN(" . generateQuestionMarks($accessibleModules) . ")";
     $param = array($maxUniqueId, $maxModifiedTime);
     foreach ($accessibleModules as $entityModule) {
         $param[] = $entityModule;
     }
     $result = $adb->pquery($moreQuery, $param);
     if ($adb->num_rows($result) > 0) {
         $output['more'] = true;
     } else {
         $output['more'] = false;
     }
     $output['uniqueid'] = $maxUniqueId;
     if (!$maxModifiedTime) {
         $modifiedtime = $mtime;
     } else {
         $modifiedtime = vtws_getSeconds($maxModifiedTime);
     }
     if (is_string($modifiedtime)) {
         $modifiedtime = intval($modifiedtime);
     }
     $output['lastModifiedTime'] = $modifiedtime;
     return $output;
 }
Beispiel #3
0
function vtws_sync($mtime, $elementType, $user)
{
    global $adb, $recordString, $modifiedTimeString;
    $ignoreModules = array("");
    $typed = true;
    $dformat = "Y-m-d H:i:s";
    $datetime = date($dformat, $mtime);
    $setypeArray = array();
    $setypeData = array();
    $setypeHandler = array();
    $setypeNoAccessArray = array();
    if (!isset($elementType) || $elementType == '' || $elementType == null) {
        $typed = false;
    }
    $adb->startTransaction();
    $q = "select crmid,setype from vtiger_crmentity where modifiedtime >? and smownerid=? and deleted=0";
    $params = array($datetime, $user->id);
    if ($typed) {
        $q = $q . " and setype=?";
        array_push($params, $elementType);
    }
    $result = $adb->pquery($q, $params);
    do {
        if ($arre) {
            if (strpos($arre["setype"], " ") === FALSE) {
                if ($arre["setype"] == 'Calendar') {
                    $seType = vtws_getCalendarEntityType($arre['crmid']);
                } else {
                    $seType = $arre["setype"];
                }
                if (array_search($seType, $ignoreModules) === FALSE) {
                    $setypeArray[$arre["crmid"]] = $seType;
                    if (!$setypeData[$seType]) {
                        $webserviceObject = VtigerWebserviceObject::fromName($adb, $seType);
                        $handlerPath = $webserviceObject->getHandlerPath();
                        $handlerClass = $webserviceObject->getHandlerClass();
                        require_once $handlerPath;
                        $setypeHandler[$seType] = new $handlerClass($webserviceObject, $user, $adb, $log);
                        $meta = $setypeHandler[$seType]->getMeta();
                        $setypeData[$seType] = new VtigerCRMObject(getTabId($meta->getEntityName()), true);
                    }
                }
            }
        }
        $arre = $adb->fetchByAssoc($result);
    } while ($arre);
    $output = array();
    $output["updated"] = array();
    foreach ($setypeArray as $key => $val) {
        $handler = $setypeHandler[$val];
        $meta = $handler->getMeta();
        if (!$meta->hasAccess() || !$meta->hasWriteAccess() || !$meta->hasPermission(EntityMeta::$RETRIEVE, $key)) {
            if (!$setypeNoAccessArray[$val]) {
                $setypeNoAccessArray[] = $val;
            }
            continue;
        }
        try {
            $error = $setypeData[$val]->read($key);
            if (!$error) {
                //Ignore records whose fetch results in an error.
                continue;
            }
            $output["updated"][] = DataTransform::filterAndSanitize($setypeData[$val]->getFields(), $meta);
        } catch (WebServiceException $e) {
            //ignore records the user doesn't have access to.
            continue;
        } catch (Exception $e) {
            throw new WebServiceException(WebServiceErrorCode::$INTERNALERROR, "Unknown Error while processing request");
        }
    }
    $setypeArray = array();
    $setypeData = array();
    $q = "select crmid,setype,modifiedtime from vtiger_crmentity where modifiedtime >? and smownerid=? and deleted=1";
    $params = array($datetime, $user->id);
    if ($typed) {
        $q = $q . " and setype=?";
        array_push($params, $elementType);
    }
    $result = $adb->pquery($q, $params);
    do {
        if ($arre) {
            if (strpos($arre["setype"], " ") === FALSE) {
                if ($arre["setype"] == 'Calendar') {
                    $seType = vtws_getCalendarEntityType($arre['crmid']);
                } else {
                    $seType = $arre["setype"];
                }
                if (array_search($seType, $ignoreModules) === FALSE) {
                    $setypeArray[$arre["crmid"]] = $seType;
                    if (!$setypeData[$seType]) {
                        $webserviceObject = VtigerWebserviceObject::fromName($adb, $seType);
                        $handlerPath = $webserviceObject->getHandlerPath();
                        $handlerClass = $webserviceObject->getHandlerClass();
                        require_once $handlerPath;
                        $setypeHandler[$seType] = new $handlerClass($webserviceObject, $user, $adb, $log);
                        $meta = $setypeHandler[$seType]->getMeta();
                        $setypeData[$seType] = new VtigerCRMObject(getTabId($meta->getEntityName()), true);
                    }
                }
            }
        }
        $arre = $adb->fetchByAssoc($result);
    } while ($arre);
    $output["deleted"] = array();
    foreach ($setypeArray as $key => $val) {
        $handler = $setypeHandler[$val];
        $meta = $handler->getMeta();
        if (!$meta->hasAccess() || !$meta->hasWriteAccess()) {
            if (!$setypeNoAccessArray[$val]) {
                $setypeNoAccessArray[] = $val;
            }
            continue;
        }
        $output["deleted"][] = vtws_getId($meta->getEntityId(), $key);
    }
    $q = "select max(modifiedtime) as modifiedtime from vtiger_crmentity where modifiedtime >? and smownerid=?";
    $params = array($datetime, $user->id);
    if ($typed) {
        $q = $q . " and setype=?";
        array_push($params, $elementType);
    } else {
        if (sizeof($setypeNoAccessArray) > 0) {
            $q = $q . " and setype not in ('" . generateQuestionMarks($setypeNoAccessArray) . "')";
            array_push($params, $setypeNoAccessArray);
        }
    }
    $result = $adb->pquery($q, $params);
    $arre = $adb->fetchByAssoc($result);
    $modifiedtime = $arre['modifiedtime'];
    if (!$modifiedtime) {
        $modifiedtime = $mtime;
    } else {
        $modifiedtime = vtws_getSeconds($modifiedtime);
    }
    if (is_string($modifiedtime)) {
        $modifiedtime = intval($modifiedtime);
    }
    $output['lastModifiedTime'] = $modifiedtime;
    $error = $adb->hasFailedTransaction();
    $adb->completeTransaction();
    if ($error) {
        throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR, "Database error while performing required operation");
    }
    VTWS_PreserveGlobal::flush();
    return $output;
}