.gitignore000064400000000047144761607110006544 0ustar00/vendor/ /tests/ composer.lock /vtiger/bootstrap.php000064400000000732144761607110007303 0ustar00getComposer()->getConfig()->get('vendor-dir'); $setup = false; if(file_exists($vendorDir."/boru/vtigertools/bootstrap.php")) { copy($vendorDir."/boru/vtigertools/bootstrap.php",$vendorDir."/bootstrap.php"); $setup = true; } elseif(file_exists($vendorDir."/../bootstrap.php")) { copy($vendorDir."/../bootstrap.php",$vendorDir."/bootstrap.php"); $setup = true; } if($setup) { echo "******************************\n"; echo "VtigerTools Bootstrap is ready\nAdd To any script/action in Vtiger to autoload:\n"; echo "\trequire_once('vendor/bootstrap.php');\n"; echo "******************************\n"; } } }src/VtigerTools.php000064400000010424144761607110010335 0ustar00false, "info"=>false, "debug"=>false, "warn"=>false, "error"=>false, ]; public static function init($sourceDirectory=null) { static::$loader = new Loader($sourceDirectory); static::$vtigerRoot = static::$loader->getVtigerDirectory(); static::initDebugger(); } public static function getIncludes($force=false) { if(empty(static::$includes) || $force) { if(!is_null(static::$loader)) { $includes = static::$loader->getIncludes(); foreach($includes as $filename) { static::$includes[] = static::$vtigerRoot->path($filename); } } else { static::$includes = []; } } return static::$includes; } public static function chdirVTiger() { static::$previousCwd = getcwd(); chdir(static::$vtigerRoot->path()); return static::$previousCwd; } public static function resetChdir() { if(!is_null(static::$previousCwd)) { chdir(static::$previousCwd); return true; } return false; } public static function debugLevel($level,$enabled=true) { if(isset(static::$debuggerSettings[$level])) { static::$debuggerSettings[$level] = $enabled; } static::initDebugger(); } private static function initDebugger() { $any = false; $debuggers = []; foreach(static::$debuggerSettings as $level=>$enabled) { if($enabled) { $any=true; $debuggers[] = $level; } } if(!$any) { dhGlobal::logger("debugger",dhGlobal::LOG_ALL & ~dhGlobal::LOG_ERROR & ~dhGlobal::LOG_WARN & ~dhGlobal::LOG_DEBUG & ~dhGlobal::LOG_INFO & ~dhGlobal::LOG_TRACE,false,false); } else { dhGlobal::logger("debugger",$debuggers,true,false); } } /** * dhGlobal:db() wrapper * @param mixed $config * @param string $driver * @return dhDB * @throws Exception */ public static function db($config=null,$driver="Mysql") { return dhGlobal::db($config,$driver); } /** * dhGlobal::outLine() wrapper * @param mixed $args * @return void */ public static function outLine(...$args) { return dhGlobal::outLine(...$args); } /** * dhutils Queue convinience static function - returns a $queue object. * @param mixed $max * @param mixed $retriesOnError * @param mixed $visualize * @param int $workerErrorLimit * @param mixed $workerBootstrap defaults to VtigerTools bootstrap script, false to disable * @return Queue */ public static function Queue($max = null, $retriesOnError = null, $visualize = null, $workerErrorLimit = 0,$workerBootstrap=null) { if(is_null($workerBootstrap)) { if(file_exists(__DIR__."/../bootstrap.php")) { $workerBootstrap = __DIR__."/../bootstrap.php"; } } elseif($workerBootstrap === false) { $workerBootstrap = null; } $queue = new Queue($max,$workerBootstrap,$retriesOnError,$visualize,$workerErrorLimit); $queue->setBootstrapAsCallable(false); } public static function trace(...$args) { dhGlobal::trace(...$args); } public static function info(...$args) { dhGlobal::info(...$args); } public static function debug(...$args) { dhGlobal::debug(...$args); } public static function warn(...$args) { dhGlobal::warn(...$args); } public static function error(...$args) { dhGlobal::error(...$args); } }src/loader/Loader.php000064400000013171144761607110010532 0ustar00vtigerDirectory = $this->findVtigerRootDirectory($sourceDirectory)) === false) { throw new \Exception("Unable to find vtiger within the path provided."); } $this->vtigerVersionString = $this->detectVtigerVersion(); $versionClass = ""; if(!empty($this->vtigerVersionString)) { $t = explode(".",$this->vtigerVersionString); $versionClass = "\\boru\\vtigertools\\loader\\versions\\Vtiger".$t[0].$t[1]."0"; if(class_exists($versionClass)) { $this->vtigerVersion = new $versionClass($this->vtigerDirectory); } } if(is_null($this->vtigerVersion)) { throw new \Exception("Unable to load VtigerVersion file $versionClass"); } $this->includes = $this->vtigerVersion->getIncludes(); $this->initDb(); if($this->vtigerVersion->needsHTMLPurifierFix()) { $this->HTMLPurifierFix($this->vtigerVersion->getHtmlPurifierFile()); } } private function initDb() { $db = dhDB::fromVtigerConfig($this->vtigerDirectory->path("config.inc.php")); dhGlobal::set("dhDB",$db); } private function detectVtigerVersion() { $versionFile = new File(["path"=>$this->vtigerDirectory->path("vtigerversion.php")]); $contents = $versionFile->content(["lineFilter"=>function($line) { if(substr($line,0,strlen('$vtiger_current_version')) == '$vtiger_current_version') { return $line; } else { return false; } }]); if(!empty($contents)) { $arr = explode("=",$contents,2); if(isset($arr[1])) { $val = dhGlobal::rtrimString(";",$arr[1]); $val = dhGlobal::btrimString(" ",$val); $val = dhGlobal::btrimString("'",$val); $val = dhGlobal::ltrimString(":",$val); return $val; } else { throw new \Exception("Unable to identify vtiger version"); } } } /** * Find the VTiger directory starting with $directory (__DIR__ if not provided) * @param null|string * @return string|false */ private function findVtigerRootDirectory($directory=null) { if(is_null($directory) || empty($directory)) { $directory = __DIR__; } $dirParts = explode(DIRECTORY_SEPARATOR,$directory); if(($dir = $this->checkIsVtigerDirectory($directory)) !== false) { //config.inc.php exists in this directory.. weird but ok.. return $dir; } $continue=true; while($continue) { $dropoff = array_pop($dirParts); if(empty($dirParts)) { $continue=false; break; } $dirPath = implode(DIRECTORY_SEPARATOR,$dirParts); if(($dir = $this->checkIsVtigerDirectory($dirPath)) !== false) { return $dir; } } return false; } private function checkIsVtigerDirectory($directoryPathString) { $filesRequiredForVtiger = [ "config.inc.php", "index.php", "vtigerversion.php", "config.php", "tabdata.php", ]; if(($dir = dhGlobal::dirIfExists($directoryPathString)) !== false) { foreach($filesRequiredForVtiger as $fileName) { if($dir->file($fileName) === false) { return false; } } return $dir; } return false; } public function HTMLPurifierFix($fileName) { $file = dhGlobal::fileIfExists($this->vtigerDirectory->path($fileName)); if($file !== false) { $hasChanged = false; $contents = $file->content(["lineFilter"=>function($line) use (&$hasChanged) { $matches = []; if(preg_match("/^(\s*)include_once \('(include|libraries)\/htmlpurifier\/library\/HTMLPurifier.auto.php'\);/",$line,$matches) === 1) { if(count($matches)>1) { $line = str_replace("HTMLPurifier.auto.php","HTMLPurifier/Bootstrap.php",$line); $line.="\n"; $line.=$matches[1]."spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload'));"; $hasChanged=true; } } return $line; }]); if($hasChanged) { $file->write($contents); } } } /** * Get the value of includes * @return array */ public function getIncludes() { return $this->includes; } /** * Get the value of vtigerDirectory * @return Directory */ public function getVtigerDirectory() { return $this->vtigerDirectory; } /** * Get the value of vtigerVersion * @return mixed */ public function getVtigerVersion() { return $this->vtigerVersion; } }src/loader/VersionInterface.php000064400000000440144761607110012565 0ustar00rootDirectory = $directory; } public function getIncludes() { return $this->includes; } public function version() { return $this->version; } public function needsHTMLPurifierFix() { return $this->needsHTMLPurifierFix; } public function getHtmlPurifierFile() { return $this->htmlPurifierFile; } }src/loader/versions/Vtiger530.php000064400000001060144761607110012656 0ustar00blockLabel = $blockLabel; $this->module($module); if($this->create) { $this->create(); } } public function create() { if($this->module instanceof Module && !$this->exists) { $this->instance->__create($this->getModuleInstance()); $this->exists = true; } return $this; } public function getBlock() { return $this->instance; } public function exists() { return $this->exists; } public function getModule() { return $this->module; } public function getModuleInstance() { return $this->module->getModule(); } public function module($module) { if(is_null($module)) { return $this; } if(is_object($module) && $module instanceof Module) { $this->module = $module; } else { $this->module = new Module($module); } if(($instance = $this->module->blockInstance($this->fieldLabel)) !== false) { $this->instance = $instance; $this->exists = true; } else { $this->instance = new \Vtiger_Block(); $this->exists = false; $this->instance->name = $this->blockLabel; } return $this; } public function addField(Field $field) { $field->getVTFieldInstance()->__create($this->getBlock()); return $this; } }src/structure/Field.php000064400000040630144761607110011141 0ustar00fieldName($fieldName); $this->columnName($fieldName); $this->fieldLabel($fieldLabel); if(!empty($options)) { $this->setFromArray($options); } } public function getVTFieldInstance($force=false) { if(is_null($this->instance) || $force) { $this->instance = new \Vtiger_Field(); $this->instance->initialize($this->get()); if(!is_null($this->columnType)) { $this->instance->columnType = $this->columnType(); } if(!empty($this->picklistValues)) { $this->instance->setPicklistValues($this->picklistValues()); } if(!empty($this->relatedModules)) { $this->instance->setRelatedModules($this->relatedModules()); } } return $this->instance; } public function get() { return [ "fieldname" => $this->fieldName(), "fieldlabel" => $this->fieldLabel(), "columnname" => $this->columnName(), "tablename" => $this->tableName(), "uitype" => $this->uiType(), "typeofdata" => $this->typeOfData(), "helpinfo" => $this->helpInfo(), "masseditable" => $this->massEdit(), "displaytype" => $this->displayType(), "generatedtype" => $this->generatedType(), "readonly" => $this->readOnly(), "presence" => $this->presence(), "defaultvalue" => $this->defaultValue(), "quickcreate" => $this->quickCreate(), "sequence" => $this->sequence(), "summaryfield" => $this->summaryField(), "isunique" => $this->isUnique(), "headerfield" => $this->headerField(), ]; } public function fieldName($fieldName=null) { return is_null($fieldName) ? $this->getFieldName() : $this->setFieldName($fieldName); } public function fieldLabel($fieldLabel=null) { return is_null($fieldLabel) ? $this->getFieldLabel() : $this->setFieldLabel($fieldLabel); } public function columnName($columnName=null) { return is_null($columnName) ? $this->getColumnName() : $this->setColumnName($columnName); } public function tableName($tableName=null) { return is_null($tableName) ? $this->getTableName() : $this->setTableName($tableName); } public function uiType($uiType=null) { return is_null($uiType) ? $this->getUiType() : $this->setUiType($uiType); } public function typeOfData($typeOfData=null) { return is_null($typeOfData) ? $this->getTypeOfData() : $this->setTypeOfData($typeOfData); } public function helpInfo($helpInfo=null) { return is_null($helpInfo) ? $this->getHelpInfo() : $this->setHelpInfo($helpInfo); } public function massEdit($massEdit=null) { return is_null($massEdit) ? $this->getMassEdit() : $this->setMassEdit($massEdit); } public function displayType($displayType=null) { return is_null($displayType) ? $this->getDisplayType() : $this->setDisplayType($displayType); } public function generatedType($generatedType=null) { return is_null($generatedType) ? $this->getGeneratedType() : $this->setGeneratedType($generatedType); } public function readOnly($readOnly=null) { return is_null($readOnly) ? $this->getReadOnly() : $this->setReadOnly($readOnly); } public function presence($presence=null) { return is_null($presence) ? $this->getPresence() : $this->setPresence($presence); } public function defaultValue($defaultValue=null) { return is_null($defaultValue) ? $this->getDefaultValue() : $this->setDefaultValue($defaultValue); } public function quickCreate($quickCreate=null) { return is_null($quickCreate) ? $this->getQuickCreate() : $this->setQuickCreate($quickCreate); } public function sequence($sequence=null) { return is_null($sequence) ? $this->getSequence() : $this->setSequence($sequence); } public function summaryField($summaryField=null) { return is_null($summaryField) ? $this->getSummaryField() : $this->setSummaryField($summaryField); } public function isUnique($isUnique=null) { return is_null($isUnique) ? $this->getIsUnique() : $this->setIsUnique($isUnique); } public function headerField($headerField=null) { return is_null($headerField) ? $this->getHeaderField() : $this->setHeaderField($headerField); } public function picklistValues($picklistValues=null) { return is_null($picklistValues) ? $this->getPicklistValues() : $this->setPicklistValues($picklistValues); } public function relatedModules($relatedModules=null) { return is_null($relatedModules) ? $this->getRelatedModules() : $this->setRelatedModules($relatedModules); } public function columnType($columnType=null) { return is_null($columnType) ? $this->getColumnType() : $this->setColumnType($columnType); } protected function isYesValue($value) { if(in_array(strtolower($value),["yes","on","y","true"])) { return true; } if($value) { return true; } return false; } public static $propToMethodMap = [ "fieldname" => "fieldName", "fieldlabel" => "fieldLabel", "columnname" => "columnName", "tablename" => "tableName", "uitype" => "uiType", "typeofdata" => "typeOfData", "helpinfo" => "helpInfo", "masseditable" => "massEdit", "displaytype" => "displayType", "generatedtype" => "generatedType", "readonly" => "readOnly", "presence" => "presence", "defaultvalue" => "defaultValue", "quickcreate" => "quickCreate", "sequence" => "sequence", "summaryfield" => "summaryField", "isunique" => "isUnique", "headerfield" => "headerField", ]; public function setFromArray($array) { foreach($array as $key=>$value) { if(isset(static::$propToMethodMap[$key])) { $method = static::$propToMethodMap[$key]; $this->$method($value); } } return $this; } public static function fromArray($array) { $instance = false; if(isset($array["fieldname"]) && isset($array["fieldlabel"])) { $instance = new self($array["fieldname"],$array["fieldlabel"]); $instance->setFromArray($array); } return $instance; } /** * Get the value of fieldName * @return mixed */ public function getFieldName() { return $this->fieldName; } /** * Set the value of fieldName * @param mixed $fieldName * @return self */ public function setFieldName($fieldName) { $this->fieldName = $fieldName; return $this; } /** * Get the value of fieldLabel * @return mixed */ public function getFieldLabel() { return $this->fieldLabel; } /** * Set the value of fieldLabel * @param mixed $fieldLabel * @return self */ public function setFieldLabel($fieldLabel) { $this->fieldLabel = $fieldLabel; return $this; } /** * Get the value of columnName * @return mixed */ public function getColumnName() { return $this->columnName; } /** * Set the value of columnName * @param mixed $columnName * @return self */ public function setColumnName($columnName) { $this->columnName = $columnName; return $this; } /** * Get the value of uiType * @return mixed */ public function getUiType() { return $this->uiType; } /** * Set the value of uiType * @param mixed $uiType * @return self */ public function setUiType($uiType) { $this->uiType = $uiType; return $this; } /** * Get the value of tableName * @return mixed */ public function getTableName() { return $this->tableName; } /** * Set the value of tableName * @param mixed $tableName * @return self */ public function setTableName($tableName) { $this->tableName = $tableName; return $this; } /** * Get the value of typeOfData * @return mixed */ public function getTypeOfData() { return $this->typeOfData; } /** * Set the value of typeOfData * @param mixed $typeOfData * @return self */ public function setTypeOfData($typeOfData) { $this->typeOfData = $typeOfData; return $this; } /** * Get the value of helpInfo * @return mixed */ public function getHelpInfo() { return $this->helpInfo; } /** * Set the value of helpInfo * @param mixed $helpInfo * @return self */ public function setHelpInfo($helpInfo) { $this->helpInfo = $helpInfo; return $this; } /** * Get the value of massEdit * @return mixed */ public function getMassEdit() { return $this->massEdit; } /** * Set the value of massEdit * @param mixed $massEdit * @return self */ public function setMassEdit($massEdit) { $this->massEdit = $this->isYesValue($massEdit) ? 1 : 0; return $this; } /** * Get the value of displayType * @return mixed */ public function getDisplayType() { return $this->displayType; } /** * Set the value of displayType * @param mixed $displayType * @return self */ public function setDisplayType($displayType) { $this->displayType = $displayType; return $this; } /** * Get the value of generatedType * @return mixed */ public function getGeneratedType() { return $this->generatedType; } /** * Set the value of generatedType * @param mixed $generatedType * @return self */ public function setGeneratedType($generatedType) { $this->generatedType = $generatedType; return $this; } /** * Get the value of readOnly * @return mixed */ public function getReadOnly() { return $this->readOnly; } /** * Set the value of readOnly * @param mixed $readOnly * @return self */ public function setReadOnly($readOnly) { $this->readOnly = $readOnly; return $this; } /** * Get the value of presence * @return mixed */ public function getPresence() { return $this->presence; } /** * Set the value of presence * @param mixed $presence * @return self */ public function setPresence($presence) { $this->presence = $presence; return $this; } /** * Get the value of defaultValue * @return mixed */ public function getDefaultValue() { return $this->defaultValue; } /** * Set the value of defaultValue * @param mixed $defaultValue * @return self */ public function setDefaultValue($defaultValue) { $this->defaultValue = $defaultValue; return $this; } /** * Get the value of quickCreate * @return mixed */ public function getQuickCreate() { return $this->quickCreate; } /** * Set the value of quickCreate * @param mixed $quickCreate * @return self */ public function setQuickCreate($quickCreate) { $this->quickCreate = $quickCreate; return $this; } /** * Get the value of sequence * @return mixed */ public function getSequence() { return $this->sequence; } /** * Set the value of sequence * @param mixed $sequence * @return self */ public function setSequence($sequence) { $this->sequence = $sequence; return $this; } /** * Get the value of summaryField * @return mixed */ public function getSummaryField() { return $this->summaryField; } /** * Set the value of summaryField * @param mixed $summaryField * @return self */ public function setSummaryField($summaryField) { $this->summaryField = $this->isYesValue($summaryField) ? 1 : 0; return $this; } /** * Get the value of isUnique * @return mixed */ public function getIsUnique() { return $this->isUnique; } /** * Set the value of isUnique * @param mixed $isUnique * @return self */ public function setIsUnique($isUnique) { $this->isUnique = $this->isYesValue($isUnique) ? 1 : 0; return $this; } /** * Get the value of headerField * @return mixed */ public function getHeaderField() { return $this->headerField; } /** * Set the value of headerField * @param mixed $headerField * @return self */ public function setHeaderField($headerField) { $this->headerField = $this->isYesValue($headerField) ? 1 : 0; return $this; } /** * Get the value of picklistValues * @return mixed */ public function getPicklistValues() { return $this->picklistValues; } /** * Set the value of picklistValues * @param mixed $picklistValues * @return self */ public function setPicklistValues($picklistValues) { $this->picklistValues = $picklistValues; return $this; } /** * Get the value of relatedModules * @return mixed */ public function getRelatedModules() { return $this->relatedModules; } /** * Set the value of relatedModules * @param mixed $relatedModules * @return self */ public function setRelatedModules($relatedModules) { $this->relatedModules = $relatedModules; return $this; } /** * Get the value of columnType * @return mixed */ public function getColumnType() { return $this->columnType; } /** * Set the value of columnType * @param mixed $columnType * @return self */ public function setColumnType($columnType) { $this->columnType = $columnType; return $this; } }src/structure/Module.php000064400000002227144761607110011343 0ustar00instance = $module; } else { $this->instance = \Vtiger_Module::getInstance($module); } if(!$this->instance) { throw new \Exception("Module $module not found"); } } public function getModule() { return $this->instance; } public function fieldInstance($fieldLabel) { if(is_null($this->instance) || $this->instance === false) { return false; } return \Vtiger_Field::getInstance($fieldLabel,$this->module); } public function blockInstance($blockLabel) { if(is_null($this->instance) || $this->instance === false) { return false; } return \Vtiger_Block::getInstance($blockLabel,$this->module); } public function inBlock($label) { return new Block($label,$this,true); } public function block($label) { return $this->inBlock($label); } }src/structure/UIType.php000064400000003755144761607110011304 0ustar00 "text", 2 => "text", 3 => "auto|key", 4 => "auto|number", 5 => "date", 6 => "dateTime", 7 => "number", 8 => "email", //comma separated list is accepted 9 => "decimal", 10 => "related", 11 => "phone", 12 => "email|User", //defaults to related User's email1 13 => "email", 15 => "rolePicklist", 16 => "picklist", 17 => "url", 19 => "textArea", 20 => "textArea", 21 => "addressStreet", 22 => "text", 23 => "date", 24 => "addressStreet", 25 => "number|0", 26 => "folder", 27 => "downloadType", 28 => "file", 30 => "reminder", 31 => "userTheme", 32 => "language", 33 => "multiPicklist", 51 => "related|Accounts", 52 => "related|User", 53 => "owner", 55 => "rolePicklist", 56 => "boolean", 57 => "related|Contacts", 58 => "related|Campaigns", 59 => "related|Products", 61 => "file", 68 => "related|Accounts,Contacts", 69 => "image", 70 => "timestamp", 71 => "currency", 72 => "currency", 73 => "related|Accounts", 75 => "related|Accounts", 76 => "related|Potentials", 77 => "related|Group", 78 => "related|Quotes", 80 => "related|SalesOrder", 81 => "related|Accounts", 83 => "productTax", 85 => "skype", 98 => "userRole", 99 => "userPassword", 101 => "userReportsTo", 104 => "userEmail", 105 => "userImage", 106 => "userName", 115 => "userStatus", 116 => "userEndHour", 117 => "currencyList", 156 => "boolean", 255 => "text", 357 => "idList", ]; }src/structure/fields/CheckboxField.php000064400000000522144761607110014052 0ustar00uiType(56); $this->typeOfData("C~O"); } }src/structure/fields/DateField.php000064400000000561144761607110013204 0ustar00uiType(5); $this->typeOfData("D~O"); $this->columnType("DATE"); } }src/structure/fields/DateTimeField.php000064400000000572144761607110014025 0ustar00uiType(5); $this->typeOfData("DT~O"); $this->columnType("DATETIME"); } }src/structure/fields/EmailField.php000064400000000517144761607110013357 0ustar00uiType(13); $this->typeOfData("E~O"); } }src/structure/fields/NumberField.php000064400000001044144761607110013554 0ustar00uiType(7); if($decimals==0) { $this->typeofData("I~O"); $this->columnType("INT(19)"); } else { $this->typeOfData("NN~O"); $this->columnType("DECIMAL(19,$decimals)"); } } }src/structure/fields/PhoneField.php000064400000000572144761607110013402 0ustar00uiType(11); $this->typeOfData("V~O"); $this->columnType("VARCHAR(20)"); } }src/structure/fields/PicklistField.php000064400000000626144761607110014113 0ustar00uiType(16); $this->typeOfData("V~O"); $this->picklistValues($picklistValues); } }src/structure/fields/RelatedField.php000064400000000677144761607110013717 0ustar00uiType(10); $this->typeOfData("V~O"); $this->columnType("BIGINT(19)"); $this->relatedModules($relatedModules); } }src/structure/fields/RolePicklistField.php000064400000000632144761607110014732 0ustar00uiType(15); $this->typeOfData("V~O"); $this->picklistValues($picklistValues); } }src/structure/fields/TextAreaField.php000064400000000572144761607110014046 0ustar00uiType(19); $this->typeOfData("V~O"); $this->columnType("LONGTEXT"); } }src/structure/fields/TextField.php000064400000000515144761607110013252 0ustar00uiType(1); $this->typeOfData("V~O"); } }src/structure/fields/UrlField.php000064400000000515144761607110013070 0ustar00uiType(17); $this->typeOfData("V~O"); } }