vtlib 文件夹,中间存储了 vTiger 的开发库。

This commit is contained in:
YUCHENG HU 2013-01-30 22:10:50 -05:00
parent 1093bc66f6
commit 1431ad5b82
22 changed files with 3705 additions and 0 deletions

267
vtlib/Vtiger/Link.php Normal file
View File

@ -0,0 +1,267 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once('vtlib/Vtiger/Utils.php');
include_once('vtlib/Vtiger/Utils/StringTemplate.php');
include_once 'vtlib/Vtiger/LinkData.php';
/**
* Provides API to handle custom links
* @package vtlib
*/
class Vtiger_Link {
var $tabid;
var $linkid;
var $linktype;
var $linklabel;
var $linkurl;
var $linkicon;
var $sequence;
var $status = false;
var $handler_path;
var $handler_class;
var $handler;
// Ignore module while selection
const IGNORE_MODULE = -1;
/**
* Constructor
*/
function __construct() {
}
/**
* Initialize this instance.
*/
function initialize($valuemap) {
$this->tabid = $valuemap['tabid'];
$this->linkid = $valuemap['linkid'];
$this->linktype=$valuemap['linktype'];
$this->linklabel=$valuemap['linklabel'];
$this->linkurl =decode_html($valuemap['linkurl']);
$this->linkicon =decode_html($valuemap['linkicon']);
$this->sequence =$valuemap['sequence'];
$this->status =$valuemap['status'];
$this->handler_path =$valuemap['handler_path'];
$this->handler_class=$valuemap['handler_class'];
$this->handler =$valuemap['handler'];
}
/**
* Get module name.
*/
function module() {
if(!empty($this->tabid)) {
return getTabModuleName($this->tabid);
}
return false;
}
/**
* Get unique id for the insertion
*/
static function __getUniqueId() {
global $adb;
return $adb->getUniqueID('vtiger_links');
}
/** Cache (Record) the schema changes to improve performance */
static $__cacheSchemaChanges = Array();
/**
* Initialize the schema (tables)
*/
static function __initSchema() {
if(empty(self::$__cacheSchemaChanges['vtiger_links'])) {
if(!Vtiger_Utils::CheckTable('vtiger_links')) {
Vtiger_Utils::CreateTable(
'vtiger_links',
'(linkid INT NOT NULL PRIMARY KEY,
tabid INT, linktype VARCHAR(20), linklabel VARCHAR(30), linkurl VARCHAR(255), linkicon VARCHAR(100), sequence INT, status INT(1) NOT NULL DEFAULT 1)',
true);
Vtiger_Utils::ExecuteQuery(
'CREATE INDEX link_tabidtype_idx on vtiger_links(tabid,linktype)');
}
self::$__cacheSchemaChanges['vtiger_links'] = true;
}
}
/**
* Add link given module
* @param Integer Module ID
* @param String Link Type (like DETAILVIEW). Useful for grouping based on pages.
* @param String Label to display
* @param String HREF value or URL to use for the link
* @param String ICON to use on the display
* @param Integer Order or sequence of displaying the link
*/
static function addLink($tabid, $type, $label, $url, $iconpath='',$sequence=0, $handlerInfo=null) {
global $adb;
self::__initSchema();
$checkres = $adb->pquery('SELECT linkid FROM vtiger_links WHERE tabid=? AND linktype=? AND linkurl=? AND linkicon=? AND linklabel=?',
Array($tabid, $type, $url, $iconpath, $label));
if(!$adb->num_rows($checkres)) {
$uniqueid = self::__getUniqueId();
$sql = 'INSERT INTO vtiger_links (linkid,tabid,linktype,linklabel,linkurl,linkicon,'.
'sequence';
$params = Array($uniqueid, $tabid, $type, $label, $url, $iconpath, $sequence);
if(!empty($handlerInfo)) {
$sql .= (', handler_path, handler_class, handler');
$params[] = $handlerInfo['path'];
$params[] = $handlerInfo['class'];
$params[] = $handlerInfo['method'];
}
$sql .= (') VALUES ('.generateQuestionMarks($params).')');
$adb->pquery($sql, $params);
self::log("Adding Link ($type - $label) ... DONE");
}
}
/**
* Delete link of the module
* @param Integer Module ID
* @param String Link Type (like DETAILVIEW). Useful for grouping based on pages.
* @param String Display label
* @param String URL of link to lookup while deleting
*/
static function deleteLink($tabid, $type, $label, $url=false) {
global $adb;
self::__initSchema();
if($url) {
$adb->pquery('DELETE FROM vtiger_links WHERE tabid=? AND linktype=? AND linklabel=? AND linkurl=?',
Array($tabid, $type, $label, $url));
self::log("Deleting Link ($type - $label - $url) ... DONE");
} else {
$adb->pquery('DELETE FROM vtiger_links WHERE tabid=? AND linktype=? AND linklabel=?',
Array($tabid, $type, $label));
self::log("Deleting Link ($type - $label) ... DONE");
}
}
/**
* Delete all links related to module
* @param Integer Module ID.
*/
static function deleteAll($tabid) {
global $adb;
self::__initSchema();
$adb->pquery('DELETE FROM vtiger_links WHERE tabid=?', Array($tabid));
self::log("Deleting Links ... DONE");
}
/**
* Get all the links related to module
* @param Integer Module ID.
*/
static function getAll($tabid) {
return self::getAllByType($tabid);
}
/**
* Get all the link related to module based on type
* @param Integer Module ID
* @param mixed String or List of types to select
* @param Map Key-Value pair to use for formating the link url
*/
static function getAllByType($tabid, $type=false, $parameters=false) {
global $adb, $current_user;
self::__initSchema();
$multitype = false;
if($type) {
// Multiple link type selection?
if(is_array($type)) {
$multitype = true;
if($tabid === self::IGNORE_MODULE) {
$sql = 'SELECT * FROM vtiger_links WHERE linktype IN ('.
Vtiger_Utils::implodestr('?', count($type), ',') .') ';
$params = $type;
$permittedTabIdList = getPermittedModuleIdList();
if(count($permittedTabIdList) > 0 && $current_user->is_admin !== 'on') {
$sql .= ' and tabid IN ('.
Vtiger_Utils::implodestr('?', count($permittedTabIdList), ',').')';
$params[] = $permittedTabIdList;
}
$result = $adb->pquery($sql, Array($adb->flatten_array($params)));
} else {
$result = $adb->pquery('SELECT * FROM vtiger_links WHERE tabid=? AND linktype IN ('.
Vtiger_Utils::implodestr('?', count($type), ',') .')',
Array($tabid, $adb->flatten_array($type)));
}
} else {
// Single link type selection
if($tabid === self::IGNORE_MODULE) {
$result = $adb->pquery('SELECT * FROM vtiger_links WHERE linktype=?', Array($type));
} else {
$result = $adb->pquery('SELECT * FROM vtiger_links WHERE tabid=? AND linktype=?', Array($tabid, $type));
}
}
} else {
$result = $adb->pquery('SELECT * FROM vtiger_links WHERE tabid=?', Array($tabid));
}
$strtemplate = new Vtiger_StringTemplate();
if($parameters) {
foreach($parameters as $key=>$value) $strtemplate->assign($key, $value);
}
$instances = Array();
if($multitype) {
foreach($type as $t) $instances[$t] = Array();
}
while($row = $adb->fetch_array($result)){
$instance = new self();
$instance->initialize($row);
if(!empty($row['handler_path']) && isFileAccessible($row['handler_path'])) {
require_once $row['handler_path'];
$linkData = new Vtiger_LinkData($instance, $current_user);
$ignore = call_user_func(array($row['handler_class'], $row['handler']), $linkData);
if(!$ignore) {
self::log("Ignoring Link ... ".var_export($row, true));
continue;
}
}
if($parameters) {
$instance->linkurl = $strtemplate->merge($instance->linkurl);
$instance->linkicon= $strtemplate->merge($instance->linkicon);
}
if($multitype) {
$instances[$instance->linktype][] = $instance;
} else {
$instances[] = $instance;
}
}
return $instances;
}
/**
* 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, $delimit=true) {
Vtiger_Utils::Log($message, $delimit);
}
/**
* Checks whether the user is admin or not
* @param Vtiger_LinkData $linkData
* @return Boolean
*/
static function isAdmin($linkData) {
$user = $linkData->getUser();
return $user->is_admin == 'on' || $user->column_fields['is_admin'] == 'on';
}
}
?>

66
vtlib/Vtiger/LinkData.php Normal file
View File

@ -0,0 +1,66 @@
<?php
/* +*******************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
*
* ******************************************************************************* */
/**
* @author MAK
*/
/**
* Description of LinkData
*
* @author MAK
*/
class Vtiger_LinkData {
protected $input;
protected $link;
protected $user;
protected $module;
public function __construct($link, $user, $input = null) {
global $currentModule;
$this->link = $link;
$this->user = $user;
$this->module = $currentModule;
if(empty($input)) {
$this->input = $_REQUEST;
} else {
$this->input = $input;
}
}
public function getInputParameter($name) {
return $this->input[$name];
}
/**
*
* @return Vtiger_Link
*/
public function getLink() {
return $this->link;
}
/**
*
* @return Users
*/
public function getUser() {
return $this->user;
}
public function getModule() {
return $this->module;
}
}
?>

279
vtlib/Vtiger/Mailer.php Normal file
View File

@ -0,0 +1,279 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
require_once('modules/Emails/class.phpmailer.php');
include_once('include/utils/CommonUtils.php');
include_once('config.inc.php');
include_once('include/database/PearDatabase.php');
include_once('vtlib/Vtiger/Utils.php');
include_once('vtlib/Vtiger/Event.php');
/**
* Provides API to work with PHPMailer & Email Templates
* @package vtlib
*/
class Vtiger_Mailer extends PHPMailer {
var $_serverConfigured = false;
/**
* Constructor
*/
function __construct() {
$this->initialize();
}
/**
* Get the unique id for insertion
* @access private
*/
function __getUniqueId() {
global $adb;
return $adb->getUniqueID('vtiger_mailer_queue');
}
/**
* Initialize this instance
* @access private
*/
function initialize() {
$this->IsSMTP();
global $adb;
$result = $adb->pquery("SELECT * FROM vtiger_systems WHERE server_type=?", Array('email'));
if($adb->num_rows($result)) {
$this->Host = $adb->query_result($result, 0, 'server');
$this->Username = $adb->query_result($result, 0, 'server_username');
$this->Password = $adb->query_result($result, 0, 'server_password');
$this->SMTPAuth = $adb->query_result($result, 0, 'smtp_auth');
if(empty($this->SMTPAuth)) $this->SMTPAuth = false;
$this->ConfigSenderInfo($adb->query_result($result, 0, 'from_email_field'));
$this->_serverConfigured = true;
$this->Sender= getReturnPath($this->Host);
}
}
/**
* Reinitialize this instance for use
* @access private
*/
function reinitialize() {
$this->to = Array();
$this->cc = Array();
$this->bcc = Array();
$this->ReplyTo = Array();
$this->Body = '';
$this->Subject ='';
$this->attachment = Array();
}
/**
* Initialize this instance using mail template
* @access private
*/
function initFromTemplate($emailtemplate) {
global $adb;
$result = $adb->pquery("SELECT * from vtiger_emailtemplates WHERE templatename=? AND foldername=?",
Array($emailtemplate, 'Public'));
if($adb->num_rows($result)) {
$this->IsHTML(true);
$usesubject = $adb->query_result($result, 0, 'subject');
$usebody = decode_html($adb->query_result($result, 0, 'body'));
$this->Subject = $usesubject;
$this->Body = $usebody;
return true;
}
return false;
}
/**
*Adding signature to mail
*/
function addSignature($userId) {
global $adb;
$sign = nl2br($adb->query_result($adb->pquery("select signature from vtiger_users where id=?", array($userId)),0,"signature"));
$this->Signature = $sign;
}
/**
* Configure sender information
*/
function ConfigSenderInfo($fromemail, $fromname='', $replyto='') {
if(empty($fromname)) $fromname = $fromemail;
$this->From = $fromemail;
$this->FromName = $fromname;
$this->AddReplyTo($replyto);
}
/**
* Overriding default send
*/
function Send($sync=false, $linktoid=false) {
if(!$this->_serverConfigured) return;
if($sync) return parent::Send();
$this->__AddToQueue($linktoid);
return true;
}
/**
* Send mail using the email template
* @param String Recipient email
* @param String Recipient name
* @param String vtiger CRM Email template name to use
*/
function SendTo($toemail, $toname='', $emailtemplate=false, $linktoid=false, $sync=false) {
if(empty($toname)) $toname = $toemail;
$this->AddAddress($toemail, $toname);
if($emailtemplate) $this->initFromTemplate($emailtemplate);
return $this->Send($sync, $linktoid);
}
/** Mail Queue **/
// Check if this instance is initialized.
var $_queueinitialized = false;
function __initializeQueue() {
if(!$this->_queueinitialized) {
if(!Vtiger_Utils::CheckTable('vtiger_mailer_queue')) {
Vtiger_Utils::CreateTable('vtiger_mailer_queue',
'(id INT NOT NULL PRIMARY KEY,
fromname VARCHAR(100), fromemail VARCHAR(100),
mailer VARCHAR(10), content_type VARCHAR(15), subject VARCHAR(999), body TEXT, relcrmid INT,
failed INT(1) NOT NULL DEFAULT 0, failreason VARCHAR(255))',
true);
}
if(!Vtiger_Utils::CheckTable('vtiger_mailer_queueinfo')) {
Vtiger_Utils::CreateTable('vtiger_mailer_queueinfo',
'(id INTEGER, name VARCHAR(100), email VARCHAR(100), type VARCHAR(7))',
true);
}
if(!Vtiger_Utils::CheckTable('vtiger_mailer_queueattachments')) {
Vtiger_Utils::CreateTable('vtiger_mailer_queueattachments',
'(id INTEGER, path TEXT, name VARCHAR(100), encoding VARCHAR(50), type VARCHAR(100))',
true);
}
$this->_queueinitialized = true;
}
return true;
}
/**
* Add this mail to queue
*/
function __AddToQueue($linktoid) {
if($this->__initializeQueue()) {
global $adb;
$uniqueid = self::__getUniqueId();
$adb->pquery('INSERT INTO vtiger_mailer_queue(id,fromname,fromemail,content_type,subject,body,mailer,relcrmid) VALUES(?,?,?,?,?,?,?,?)',
Array($uniqueid, $this->FromName, $this->From, $this->ContentType, $this->Subject, $this->Body, $this->Mailer, $linktoid));
$queueid = $adb->database->Insert_ID();
foreach($this->to as $toinfo) {
if(empty($toinfo[0])) continue;
$adb->pquery('INSERT INTO vtiger_mailer_queueinfo(id, name, email, type) VALUES(?,?,?,?)',
Array($queueid, $toinfo[1], $toinfo[0], 'TO'));
}
foreach($this->cc as $ccinfo) {
if(empty($ccinfo[0])) continue;
$adb->pquery('INSERT INTO vtiger_mailer_queueinfo(id, name, email, type) VALUES(?,?,?,?)',
Array($queueid, $ccinfo[1], $ccinfo[0], 'CC'));
}
foreach($this->bcc as $bccinfo) {
if(empty($bccinfo[0])) continue;
$adb->pquery('INSERT INTO vtiger_mailer_queueinfo(id, name, email, type) VALUES(?,?,?,?)',
Array($queueid, $bccinfo[1], $bccinfo[0], 'BCC'));
}
foreach($this->ReplyTo as $rtoinfo) {
if(empty($rtoinfo[0])) continue;
$adb->pquery('INSERT INTO vtiger_mailer_queueinfo(id, name, email, type) VALUES(?,?,?,?)',
Array($queueid, $rtoinfo[1], $rtoinfo[0], 'RPLYTO'));
}
foreach($this->attachment as $attachmentinfo) {
if(empty($attachmentinfo[0])) continue;
$adb->pquery('INSERT INTO vtiger_mailer_queueattachments(id, path, name, encoding, type) VALUES(?,?,?,?,?)',
Array($queueid, $attachmentinfo[0], $attachmentinfo[2], $attachmentinfo[3], $attachmentinfo[4]));
}
}
}
/**
* Dispatch (send) email that was queued.
*/
static function dispatchQueue(Vtiger_Mailer_Listener $listener=null) {
global $adb;
if(!Vtiger_Utils::CheckTable('vtiger_mailer_queue')) return;
$mailer = new self();
$queue = $adb->query('SELECT * FROM vtiger_mailer_queue WHERE failed != 1');
if($adb->num_rows($queue)) {
for($index = 0; $index < $adb->num_rows($queue); ++$index) {
$mailer->reinitialize();
$queue_record = $adb->fetch_array($queue, $index);
$queueid = $queue_record['id'];
$relcrmid= $queue_record['relcrmid'];
$mailer->From = $queue_record['fromemail'];
$mailer->From = $queue_record['fromname'];
$mailer->Subject=$queue_record['subject'];
$mailer->Body = decode_html($queue_record['body']);
$mailer->Mailer=$queue_record['mailer'];
$mailer->ContentType = $queue_record['content_type'];
$emails = $adb->pquery('SELECT * FROM vtiger_mailer_queueinfo WHERE id=?', Array($queueid));
for($eidx = 0; $eidx < $adb->num_rows($emails); ++$eidx) {
$email_record = $adb->fetch_array($emails, $eidx);
if($email_record[type] == 'TO') $mailer->AddAddress($email_record[email], $email_record[name]);
else if($email_record[type] == 'CC')$mailer->AddCC($email_record[email], $email_record[name]);
else if($email_record[type] == 'BCC')$mailer->AddBCC($email_record[email], $email_record[name]);
else if($email_record[type] == 'RPLYTO')$mailer->AddReplyTo($email_record[email], $email_record[name]);
}
$attachments = $adb->pquery('SELECT * FROM vtiger_mailer_queueattachments WHERE id=?', Array($queueid));
for($aidx = 0; $aidx < $adb->num_rows($attachments); ++$aidx) {
$attachment_record = $adb->fetch_array($attachments, $aidx);
if($attachment_record['path'] != '') {
$mailer->AddAttachment($attachment_record['path'], $attachment_record['name'],
$attachment_record['encoding'], $attachment_record['type']);
}
}
$sent = $mailer->Send(true);
if($sent) {
Vtiger_Event::trigger('vtiger.mailer.mailsent', $relcrmid);
if($listener) {
$listener->mailsent($queueid);
}
$adb->pquery('DELETE FROM vtiger_mailer_queue WHERE id=?', Array($queueid));
$adb->pquery('DELETE FROM vtiger_mailer_queueinfo WHERE id=?', Array($queueid));
$adb->pquery('DELETE FROM vtiger_mailer_queueattachments WHERE id=?', Array($queueid));
} else {
if($listener) {
$listener->mailerror($queueid);
}
$adb->pquery('UPDATE vtiger_mailer_queue SET failed=?, failreason=? WHERE id=?', Array(1, $mailer->ErrorInfo, $queueid));
}
}
}
}
}
/**
* Provides API to act on the different events triggered by send email action.
* @package vtlib
*/
abstract class Vtiger_Mailer_Listener {
function mailsent($queueid) { }
function mailerror($queueid) { }
}
?>

142
vtlib/Vtiger/Menu.php Normal file
View File

@ -0,0 +1,142 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once('vtlib/Vtiger/Utils.php');
/**
* Provides API to work with vtiger CRM Menu
* @package vtlib
*/
class Vtiger_Menu {
/** ID of this menu instance */
var $id = false;
var $label = false;
var $sequence = false;
var $visible = 0;
/**
* Constructor
*/
function __construct() {
}
/**
* Initialize this instance
* @param Array Map
* @access private
*/
function initialize($valuemap) {
$this->id = $valuemap[parenttabid];
$this->label = $valuemap[parenttab_label];
$this->sequence = $valuemap[sequence];
$this->visible = $valuemap[visible];
}
/**
* Get relation sequence to use
* @access private
*/
function __getNextRelSequence() {
global $adb;
$result = $adb->pquery("SELECT MAX(sequence) AS max_seq FROM vtiger_parenttabrel WHERE parenttabid=?",
Array($this->id));
$maxseq = $adb->query_result($result, 0, 'max_seq');
return ++$maxseq;
}
/**
* Add module to this menu instance
* @param Vtiger_Module Instance of the module
*/
function addModule($moduleInstance) {
if($this->id) {
global $adb;
$relsequence = $this->__getNextRelSequence();
$adb->pquery("INSERT INTO vtiger_parenttabrel (parenttabid,tabid,sequence) VALUES(?,?,?)",
Array($this->id, $moduleInstance->id, $relsequence));
self::log("Added to menu $this->label ... DONE");
} else {
self::log("Menu could not be found!");
}
self::syncfile();
}
/**
* Remove module from this menu instance.
* @param Vtiger_Module Instance of the module
*/
function removeModule($moduleInstance) {
if(empty($moduleInstance) || empty($moduleInstance)) {
self::log("Module instance is not set!");
return;
}
if($this->id) {
global $adb;
$adb->pquery("DELETE FROM vtiger_parenttabrel WHERE parenttabid = ? AND tabid = ?",
Array($this->id, $moduleInstance->id));
self::log("Removed $moduleInstance->name from menu $this->label ... DONE");
} else {
self::log("Menu could not be found!");
}
self::syncfile();
}
/**
* Detach module from menu
* @param Vtiger_Module Instance of the module
*/
static function detachModule($moduleInstance) {
global $adb;
$adb->pquery("DELETE FROM vtiger_parenttabrel WHERE tabid=?", Array($moduleInstance->id));
self::log("Detaching from menu ... DONE");
self::syncfile();
}
/**
* Get instance of menu by label
* @param String Menu label
*/
static function getInstance($value) {
global $adb;
$query = false;
$instance = false;
if(Vtiger_Utils::isNumber($value)) {
$query = "SELECT * FROM vtiger_parenttab WHERE parenttabid=?";
} else {
$query = "SELECT * FROM vtiger_parenttab WHERE parenttab_label=?";
}
$result = $adb->pquery($query, Array($value));
if($adb->num_rows($result)) {
$instance = new self();
$instance->initialize($adb->fetch_array($result));
}
return $instance;
}
/**
* 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) {
Vtiger_Utils::Log($message, $delim);
}
/**
* Synchronize the menu information to flat file
* @access private
*/
static function syncfile() {
self::log("Updating parent_tabdata file ... STARTED");
create_parenttab_data_file();
self::log("Updating parent_tabdata file ... DONE");
}
}
?>

202
vtlib/Vtiger/Module.php Normal file
View File

@ -0,0 +1,202 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once('vtlib/Vtiger/ModuleBasic.php');
/**
* Provides API to work with vtiger CRM Modules
* @package vtlib
*/
class Vtiger_Module extends Vtiger_ModuleBasic {
/**
* Get unique id for related list
* @access private
*/
function __getRelatedListUniqueId() {
global $adb;
return $adb->getUniqueID('vtiger_relatedlists');
}
/**
* Get related list sequence to use
* @access private
*/
function __getNextRelatedListSequence() {
global $adb;
$max_sequence = 0;
$result = $adb->pquery("SELECT max(sequence) as maxsequence FROM vtiger_relatedlists WHERE tabid=?", Array($this->id));
if($adb->num_rows($result)) $max_sequence = $adb->query_result($result, 0, 'maxsequence');
return ++$max_sequence;
}
/**
* Set related list information between other module
* @param Vtiger_Module Instance of target module with which relation should be setup
* @param String Label to display in related list (default is target module name)
* @param Array List of action button to show ('ADD', 'SELECT')
* @param String Callback function name of this module to use as handler
*
* @internal Creates table vtiger_crmentityrel if it does not exists
*/
function setRelatedList($moduleInstance, $label='', $actions=false, $function_name='get_related_list') {
global $adb;
if(empty($moduleInstance)) return;
if(!Vtiger_Utils::CheckTable('vtiger_crmentityrel')) {
Vtiger_Utils::CreateTable(
'vtiger_crmentityrel',
'(crmid INT NOT NULL, module VARCHAR(100) NOT NULL, relcrmid INT NOT NULL, relmodule VARCHAR(100) NOT NULL)',
true
);
}
$relation_id = $this->__getRelatedListUniqueId();
$sequence = $this->__getNextRelatedListSequence();
$presence = 0; // 0 - Enabled, 1 - Disabled
if(empty($label)) $label = $moduleInstance->name;
// Allow ADD action of other module records (default)
if($actions === false) $actions = Array('ADD');
$useactions_text = $actions;
if(is_array($actions)) $useactions_text = implode(',', $actions);
$useactions_text = strtoupper($useactions_text);
// Add column to vtiger_relatedlists to save extended actions
Vtiger_Utils::AddColumn('vtiger_relatedlists', 'actions', 'VARCHAR(50)');
$adb->pquery("INSERT INTO vtiger_relatedlists(relation_id,tabid,related_tabid,name,sequence,label,presence,actions) VALUES(?,?,?,?,?,?,?,?)",
Array($relation_id,$this->id,$moduleInstance->id,$function_name,$sequence,$label,$presence,$useactions_text));
self::log("Setting relation with $moduleInstance->name [$useactions_text] ... DONE");
}
/**
* Unset related list information that exists with other module
* @param Vtiger_Module Instance of target module with which relation should be setup
* @param String Label to display in related list (default is target module name)
* @param String Callback function name of this module to use as handler
*/
function unsetRelatedList($moduleInstance, $label='', $function_name='get_related_list') {
global $adb;
if(empty($moduleInstance)) return;
if(empty($label)) $label = $moduleInstance->name;
$adb->pquery("DELETE FROM vtiger_relatedlists WHERE tabid=? AND related_tabid=? AND name=? AND label=?",
Array($this->id, $moduleInstance->id, $function_name, $label));
self::log("Unsetting relation with $moduleInstance->name ... DONE");
}
/**
* Add custom link for a module page
* @param String Type can be like 'DETAILVIEW', 'LISTVIEW' etc..
* @param String Label to use for display
* @param String HREF value to use for generated link
* @param String Path to the image file (relative or absolute)
* @param Integer Sequence of appearance
*
* NOTE: $url can have variables like $MODULE (module for which link is associated),
* $RECORD (record on which link is dispalyed)
*/
function addLink($type, $label, $url, $iconpath='', $sequence=0, $handlerInfo=null) {
Vtiger_Link::addLink($this->id, $type, $label, $url, $iconpath, $sequence, $handlerInfo);
}
/**
* Delete custom link of a module
* @param String Type can be like 'DETAILVIEW', 'LISTVIEW' etc..
* @param String Display label to lookup
* @param String URL value to lookup
*/
function deleteLink($type, $label, $url=false) {
Vtiger_Link::deleteLink($this->id, $type, $label, $url);
}
/**
* Get all the custom links related to this module.
*/
function getLinks() {
return Vtiger_Link::getAll($this->id);
}
/**
* Initialize webservice setup for this module instance.
*/
function initWebservice() {
Vtiger_Webservice::initialize($this);
}
/**
* De-Initialize webservice setup for this module instance.
*/
function deinitWebservice() {
Vtiger_Webservice::uninitialize($this);
}
/**
* Get instance by id or name
* @param mixed id or name of the module
*/
static function getInstance($value) {
global $adb;
$instance = false;
$query = false;
if(Vtiger_Utils::isNumber($value)) {
$query = "SELECT * FROM vtiger_tab WHERE tabid=?";
} else {
$query = "SELECT * FROM vtiger_tab WHERE name=?";
}
$result = $adb->pquery($query, Array($value));
if($adb->num_rows($result)) {
$instance = new self();
$instance->initialize($adb->fetch_array($result));
}
return $instance;
}
/**
* Get instance of the module class.
* @param String Module name
*/
static function getClassInstance($modulename) {
if($modulename == 'Calendar') $modulename = 'Activity';
$instance = false;
$filepath = "modules/$modulename/$modulename.php";
if(Vtiger_Utils::checkFileAccessForInclusion($filepath, false)) {
include_once($filepath);
if(class_exists($modulename)) {
$instance = new $modulename();
}
}
return $instance;
}
/**
* Fire the event for the module (if vtlib_handler is defined)
*/
static function fireEvent($modulename, $event_type) {
$instance = self::getClassInstance((string)$modulename);
if($instance) {
if(method_exists($instance, 'vtlib_handler')) {
self::log("Invoking vtlib_handler for $event_type ...START");
$instance->vtlib_handler((string)$modulename, (string)$event_type);
self::log("Invoking vtlib_handler for $event_type ...DONE");
}
}
}
}
?>

View File

@ -0,0 +1,429 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once('vtlib/Vtiger/Access.php');
include_once('vtlib/Vtiger/Block.php');
include_once('vtlib/Vtiger/Field.php');
include_once('vtlib/Vtiger/Filter.php');
include_once('vtlib/Vtiger/Profile.php');
include_once('vtlib/Vtiger/Menu.php');
include_once('vtlib/Vtiger/Link.php');
include_once('vtlib/Vtiger/Event.php');
include_once('vtlib/Vtiger/Webservice.php');
include_once('vtlib/Vtiger/Version.php');
/**
* Provides API to work with vtiger CRM Module
* @package vtlib
*/
class Vtiger_ModuleBasic {
/** ID of this instance */
var $id = false;
var $name = false;
var $label = false;
var $version= 0;
var $minversion = false;
var $maxversion = false;
var $presence = 0;
var $ownedby = 0; // 0 - Sharing Access Enabled, 1 - Sharing Access Disabled
var $tabsequence = false;
var $parent = false;
var $isentitytype = true; // Real module or an extension?
var $entityidcolumn = false;
var $entityidfield = false;
var $basetable = false;
var $basetableid=false;
var $customtable=false;
var $grouptable = false;
const EVENT_MODULE_ENABLED = 'module.enabled';
const EVENT_MODULE_DISABLED = 'module.disabled';
const EVENT_MODULE_POSTINSTALL = 'module.postinstall';
const EVENT_MODULE_PREUNINSTALL= 'module.preuninstall';
const EVENT_MODULE_PREUPDATE = 'module.preupdate';
const EVENT_MODULE_POSTUPDATE = 'module.postupdate';
/**
* Constructor
*/
function __construct() {
}
/**
* Initialize this instance
* @access private
*/
function initialize($valuemap) {
$this->id = $valuemap['tabid'];
$this->name=$valuemap['name'];
$this->label=$valuemap['tablabel'];
$this->version=$valuemap['version'];
$this->presence = $valuemap['presence'];
$this->ownedby = $valuemap['ownedby'];
$this->tabsequence = $valuemap['tabsequence'];
$this->parent = $valuemap['parent'];
$this->isentitytype = $valuemap['isentitytype'];
if($this->isentitytype || $this->name == 'Users') {
// Initialize other details too
$this->initialize2();
}
}
/**
* Initialize more information of this instance
* @access private
*/
function initialize2() {
global $adb;
$result = $adb->pquery("SELECT tablename,entityidfield FROM vtiger_entityname WHERE tabid=?",
Array($this->id));
if($adb->num_rows($result)) {
$this->basetable = $adb->query_result($result, 0, 'tablename');
$this->basetableid=$adb->query_result($result, 0, 'entityidfield');
}
}
/**
* Get unique id for this instance
* @access private
*/
function __getUniqueId() {
global $adb;
$result = $adb->query("SELECT MAX(tabid) AS max_seq FROM vtiger_tab");
$maxseq = $adb->query_result($result, 0, 'max_seq');
return ++$maxseq;
}
/**
* Get next sequence to use for this instance
* @access private
*/
function __getNextSequence() {
global $adb;
$result = $adb->query("SELECT MAX(tabsequence) AS max_tabseq FROM vtiger_tab");
$maxtabseq = $adb->query_result($result, 0, 'max_tabseq');
return ++$maxtabseq;
}
/**
* Initialize vtiger schema changes.
* @access private
*/
function __handleVtigerCoreSchemaChanges() {
// Add version column to the table first
Vtiger_Utils::AddColumn('vtiger_tab', 'version', ' VARCHAR(10)');
Vtiger_Utils::AddColumn('vtiger_tab', 'parent', ' VARCHAR(30)');
}
/**
* Create this module instance
* @access private
*/
function __create() {
global $adb;
self::log("Creating Module $this->name ... STARTED");
$this->id = $this->__getUniqueId();
if(!$this->tabsequence) $this->tabsequence = $this->__getNextSequence();
if(!$this->label) $this->label = $this->name;
$customized = 1; // To indicate this is a Custom Module
$this->__handleVtigerCoreSchemaChanges();
$adb->pquery("INSERT INTO vtiger_tab (tabid,name,presence,tabsequence,tablabel,modifiedby,
modifiedtime,customized,ownedby,version,parent) VALUES (?,?,?,?,?,?,?,?,?,?,?)",
Array($this->id, $this->name, $this->presence, -1, $this->label, NULL, NULL, $customized, $this->ownedby, $this->version,$this->parent));
$useisentitytype = $this->isentitytype? 1 : 0;
$adb->pquery('UPDATE vtiger_tab set isentitytype=? WHERE tabid=?',Array($useisentitytype, $this->id));
if(!Vtiger_Utils::CheckTable('vtiger_tab_info')) {
Vtiger_Utils::CreateTable(
'vtiger_tab_info',
'(tabid INT, prefname VARCHAR(256), prefvalue VARCHAR(256), FOREIGN KEY fk_1_vtiger_tab_info(tabid) REFERENCES vtiger_tab(tabid) ON DELETE CASCADE ON UPDATE CASCADE)',
true);
}
if($this->minversion) {
$tabResult = $adb->pquery("SELECT 1 FROM vtiger_tab_info WHERE tabid=? AND prefname='vtiger_min_version'", array($this->id));
if ($adb->num_rows($tabResult) > 0) {
$adb->pquery("UPDATE vtiger_tab_info SET prefvalue=? WHERE tabid=? AND prefname='vtiger_min_version'", array($this->minversion,$this->id));
} else {
$adb->pquery('INSERT INTO vtiger_tab_info(tabid, prefname, prefvalue) VALUES (?,?,?)', array($this->id, 'vtiger_min_version', $this->minversion));
}
}
if($this->maxversion) {
$tabResult = $adb->pquery("SELECT 1 FROM vtiger_tab_info WHERE tabid=? AND prefname='vtiger_max_version'", array($this->id));
if ($adb->num_rows($tabResult) > 0) {
$adb->pquery("UPDATE vtiger_tab_info SET prefvalue=? WHERE tabid=? AND prefname='vtiger_max_version'", array($this->maxversion,$this->id));
} else {
$adb->pquery('INSERT INTO vtiger_tab_info(tabid, prefname, prefvalue) VALUES (?,?,?)', array($this->id, 'vtiger_max_version', $this->maxversion));
}
}
Vtiger_Profile::initForModule($this);
self::syncfile();
if($this->isentitytype) {
Vtiger_Access::initSharing($this);
}
self::log("Creating Module $this->name ... DONE");
}
/**
* Update this instance
* @access private
*/
function __update() {
self::log("Updating Module $this->name ... DONE");
}
/**
* Delete this instance
* @access private
*/
function __delete() {
Vtiger_Module::fireEvent($this->name,
Vtiger_Module::EVENT_MODULE_PREUNINSTALL);
global $adb;
if($this->isentitytype) {
$this->unsetEntityIdentifier();
$this->deleteRelatedLists();
}
$adb->pquery("DELETE FROM vtiger_tab WHERE tabid=?", Array($this->id));
self::log("Deleting Module $this->name ... DONE");
}
/**
* Update module version information
* @access private
*/
function __updateVersion($newversion) {
$this->__handleVtigerCoreSchemaChanges();
global $adb;
$adb->pquery("UPDATE vtiger_tab SET version=? WHERE tabid=?", Array($newversion, $this->id));
$this->version = $newversion;
self::log("Updating version to $newversion ... DONE");
}
/**
* Save this instance
*/
function save() {
if($this->id) $this->__update();
else $this->__create();
return $this->id;
}
/**
* Delete this instance
*/
function delete() {
if($this->isentitytype) {
Vtiger_Access::deleteSharing($this);
Vtiger_Access::deleteTools($this);
Vtiger_Filter::deleteForModule($this);
Vtiger_Block::deleteForModule($this);
if(method_exists($this, 'deinitWebservice')) {
$this->deinitWebservice();
}
}
$this->__delete();
Vtiger_Profile::deleteForModule($this);
Vtiger_Link::deleteAll($this->id);
Vtiger_Menu::detachModule($this);
self::syncfile();
}
/**
* Initialize table required for the module
* @param String Base table name (default modulename in lowercase)
* @param String Base table column (default modulenameid in lowercase)
*
* Creates basetable, customtable, grouptable <br>
* customtable name is basetable + 'cf'<br>
* grouptable name is basetable + 'grouprel'<br>
*/
function initTables($basetable=false, $basetableid=false) {
$this->basetable = $basetable;
$this->basetableid=$basetableid;
// Initialize tablename and index column names
$lcasemodname = strtolower($this->name);
if(!$this->basetable) $this->basetable = "vtiger_$lcasemodname";
if(!$this->basetableid)$this->basetableid=$lcasemodname . "id";
if(!$this->customtable)$this->customtable = $this->basetable . "cf";
if(!$this->grouptable)$this->grouptable = $this->basetable."grouprel";
Vtiger_Utils::CreateTable($this->basetable,"($this->basetableid INT)",true);
Vtiger_Utils::CreateTable($this->customtable,
"($this->basetableid INT PRIMARY KEY)", true);
if(Vtiger_Version::check('5.0.4', '<=')) {
Vtiger_Utils::CreateTable($this->grouptable,
"($this->basetableid INT PRIMARY KEY, groupname varchar(100))",true);
}
}
/**
* Set entity identifier field for this module
* @param Vtiger_Field Instance of field to use
*/
function setEntityIdentifier($fieldInstance) {
global $adb;
if($this->basetableid) {
if(!$this->entityidfield) $this->entityidfield = $this->basetableid;
if(!$this->entityidcolumn)$this->entityidcolumn= $this->basetableid;
}
if($this->entityidfield && $this->entityidcolumn) {
$adb->pquery("INSERT INTO vtiger_entityname(tabid, modulename, tablename, fieldname, entityidfield, entityidcolumn) VALUES(?,?,?,?,?,?)",
Array($this->id, $this->name, $fieldInstance->table, $fieldInstance->name, $this->entityidfield, $this->entityidcolumn));
self::log("Setting entity identifier ... DONE");
}
}
/**
* Unset entity identifier information
*/
function unsetEntityIdentifier() {
global $adb;
$adb->pquery("DELETE FROM vtiger_entityname WHERE tabid=?", Array($this->id));
self::log("Unsetting entity identifier ... DONE");
}
/**
* Delete related lists information
*/
function deleteRelatedLists() {
global $adb;
$adb->pquery("DELETE FROM vtiger_relatedlists WHERE tabid=?", Array($this->id));
self::log("Deleting related lists ... DONE");
}
/**
* Delete links information
*/
function deleteLinks() {
global $adb;
$adb->pquery("DELETE FROM vtiger_links WHERE tabid=?", Array($this->id));
self::log("Deleting links ... DONE");
}
/**
* Configure default sharing access for the module
* @param String Permission text should be one of ['Public_ReadWriteDelete', 'Public_ReadOnly', 'Public_ReadWrite', 'Private']
*/
function setDefaultSharing($permission_text='Public_ReadWriteDelete') {
Vtiger_Access::setDefaultSharing($this, $permission_text);
}
/**
* Allow module sharing control
*/
function allowSharing() {
Vtiger_Access::allowSharing($this, true);
}
/**
* Disallow module sharing control
*/
function disallowSharing() {
Vtiger_Access::allowSharing($this, false);
}
/**
* Enable tools for this module
* @param mixed String or Array with value ['Import', 'Export', 'Merge']
*/
function enableTools($tools) {
if(is_string($tools)) {
$tools = Array(0 => $tools);
}
foreach($tools as $tool) {
Vtiger_Access::updateTool($this, $tool, true);
}
}
/**
* Disable tools for this module
* @param mixed String or Array with value ['Import', 'Export', 'Merge']
*/
function disableTools($tools) {
if(is_string($tools)) {
$tools = Array(0 => $tools);
}
foreach($tools as $tool) {
Vtiger_Access::updateTool($this, $tool, false);
}
}
/**
* Add block to this module
* @param Vtiger_Block Instance of block to add
*/
function addBlock($blockInstance) {
$blockInstance->save($this);
return $this;
}
/**
* Add filter to this module
* @param Vtiger_Filter Instance of filter to add
*/
function addFilter($filterInstance) {
$filterInstance->save($this);
return $this;
}
/**
* Get all the fields of the module or block
* @param Vtiger_Block Instance of block to use to get fields, false to get all the block fields
*/
function getFields($blockInstance=false) {
$fields = false;
if($blockInstance) $fields = Vtiger_Field::getAllForBlock($blockInstance, $this);
else $fields = Vtiger_Field::getAllForModule($this);
return $fields;
}
/**
* 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, $delimit=true) {
Vtiger_Utils::Log($message, $delimit);
}
/**
* Synchronize the menu information to flat file
* @access private
*/
static function syncfile() {
self::log("Updating tabdata file ... ", false);
create_tab_data_file();
self::log("DONE");
}
}
?>

117
vtlib/Vtiger/Net/Client.php Normal file
View File

@ -0,0 +1,117 @@
<?php
/*+***********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
*************************************************************************************/
include 'vtlib/thirdparty/network/Request.php';
/**
* Provides API to work with HTTP Connection.
* @package vtlib
*/
class Vtiger_Net_Client {
var $client;
var $url;
var $response;
/**
* Constructor
* @param String URL of the site
* Example:
* $client = new Vtiger_New_Client('http://www.vtiger.com');
*/
function __construct($url) {
$this->setURL($url);
}
/**
* Set another url for this instance
* @param String URL to use go forward
*/
function setURL($url) {
$this->url = $url;
$this->client = new HTTP_Request();
$this->response = false;
}
/**
* Set custom HTTP Headers
* @param Map HTTP Header and Value Pairs
*/
function setHeaders($values) {
foreach($values as $key=>$value) {
$this->client->addHeader($key, $value);
}
}
/**
* Perform a GET request
* @param Map key-value pair or false
* @param Integer timeout value
*/
function doGet($params=false, $timeout=null) {
if($timeout) $this->client->_timeout = $timeout;
$this->client->setURL($this->url);
$this->client->setMethod(HTTP_REQUEST_METHOD_GET);
if($params) {
foreach($params as $key=>$value)
$this->client->addQueryString($key, $value);
}
$this->response = $this->client->sendRequest();
$content = false;
if(!$this->wasError()) {
$content = $this->client->getResponseBody();
}
$this->disconnect();
return $content;
}
/**
* Perform a POST request
* @param Map key-value pair or false
* @param Integer timeout value
*/
function doPost($params=false, $timeout=null) {
if($timeout) $this->client->_timeout = $timeout;
$this->client->setURL($this->url);
$this->client->setMethod(HTTP_REQUEST_METHOD_POST);
if($params) {
if(is_string($params)) $this->client->addRawPostData($params);
else {
foreach($params as $key=>$value)
$this->client->addPostData($key, $value);
}
}
$this->response = $this->client->sendRequest();
$content = false;
if(!$this->wasError()) {
$content = $this->client->getResponseBody();
}
$this->disconnect();
return $content;
}
/**
* Did last request resulted in error?
*/
function wasError() {
return PEAR::isError($this->response);
}
/**
* Disconnect this instance
*/
function disconnect() {
$this->client->disconnect();
}
}
?>

View File

@ -0,0 +1,12 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
class Vtiger_PDF_Frame {
var $x, $y, $h, $w;
}

View File

@ -0,0 +1,192 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/TCPDF.php';
include_once dirname(__FILE__) . '/Frame.php';
class Vtiger_PDF_Generator {
private $headerViewer = false, $footerViewer = false, $contentViewer = false, $pagerViewer = false;
private $headerFrame, $footerFrame, $contentFrame;
private $pdf;
private $isFirstPage = false;
private $isLastPage = false;
private $totalWidth = 0;
private $totalHeight = 0;
function __construct() {
$this->pdf = new Vtiger_PDF_TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT);
$this->pdf->setPrintHeader(false);
$this->pdf->setPrintFooter(false);
}
function setHeaderViewer($viewer) {
$this->headerViewer = $viewer;
}
function setFooterViewer($viewer) {
$this->footerViewer = $viewer;
}
function setContentViewer($viewer) {
$this->contentViewer = $viewer;
}
function setPagerViewer($viewer) {
$this->pagerViewer = $viewer;
}
function getHeaderFrame() {
return $this->headerFrame;
}
function getFooterFrame() {
return $this->footerFrame;
}
function getContentFrame() {
return $this->contentFrame;
}
function getPDF() {
return $this->pdf;
}
function onLastPage() {
return $this->isLastPage;
}
function onFirstPage() {
return $this->isFirstPage;
}
function getTotalWidth() {
return $this->totalWidth;
}
function getTotalHeight() {
return $this->totalHeight;
}
function createLastPage() {
// Detect if there is a last page already.
if($this->isLastPage) return false;
// Check if the last page is required for adding footer
if(!$this->footerViewer || !$this->footerViewer->onLastPage()) return false;
$pdf = $this->pdf;
// Create a new page
$pdf->AddPage();
$this->isFirstPage = false;
$this->isLastPage = true;
$margins = $pdf->getMargins();
$totalHeightFooter = $this->footerViewer? $this->footerViewer->totalHeight($this) : 0;
if ($totalHeightFooter) {
$this->footerFrame = new Vtiger_PDF_Frame();
$this->footerFrame->x = $pdf->GetX();
$this->footerFrame->y = $margins['top'];
$this->footerFrame->h = $totalHeightFooter;
$this->footerFrame->w = $this->totalWidth;
$this->footerViewer->initDisplay($this);
$this->footerViewer->display($this);
}
if($this->pagerViewer) {
$this->pagerViewer->display($this);
}
return true;
}
function createPage($isLastPage = false) {
$pdf = $this->pdf;
// Create a new page
$pdf->AddPage();
if($isLastPage) {
$this->isFirstPage = false;
$this->isLastPage = true;
} else {
if($pdf->getPage() > 1) $this->isFirstPage = false;
else $this->isFirstPage = true;
}
$margins = $pdf->getMargins();
$this->totalWidth = $pdf->getPageWidth()-$margins['left']-$margins['right'];
$this->totalHeight = $totalHeight = $pdf->getPageHeight() - $margins['top'] - $margins['bottom'];
$totalHeightHeader = $this->headerViewer? $this->headerViewer->totalHeight($this) : 0;
$totalHeightFooter = $this->footerViewer? $this->footerViewer->totalHeight($this) : 0;
$totalHeightContent= $this->contentViewer->totalHeight($this);
if ($totalHeightContent === 0) $totalHeightContent = $totalHeight - $totalHeightHeader - $totalHeightFooter;
if ($totalHeightHeader) {
$this->headerFrame = new Vtiger_PDF_Frame();
$this->headerFrame->x = $pdf->GetX();
$this->headerFrame->y = $pdf->GetY();
$this->headerFrame->h = $totalHeightHeader;
$this->headerFrame->w = $this->totalWidth;
$this->headerViewer->initDisplay($this);
$this->headerViewer->display($this);
}
// ContentViewer
$this->contentFrame = new Vtiger_PDF_Frame();
$this->contentFrame->x = $pdf->GetX();
$this->contentFrame->y = $pdf->GetY();
$this->contentFrame->h = $totalHeightContent;
$this->contentFrame->w = $this->totalWidth;
$this->contentViewer->initDisplay($this);
if ($totalHeightFooter) {
$this->footerFrame = new Vtiger_PDF_Frame();
$this->footerFrame->x = $pdf->GetX();
$this->footerFrame->y = $totalHeight+$margins['top']-$totalHeightFooter;
$this->footerFrame->h = $totalHeightFooter;
$this->footerFrame->w = $this->totalWidth;
$this->footerViewer->initDisplay($this);
$this->footerViewer->display($this);
}
if($this->pagerViewer) {
$this->pagerViewer->display($this);
}
}
function generate($name, $outputMode='D') {
$this->contentViewer->display($this);
$this->pdf->Output($name, $outputMode);
}
function getImageSize($file) {
// get image dimensions
$imsize = @getimagesize($file);
if ($imsize === FALSE) {
// encode spaces on filename
$file = str_replace(' ', '%20', $file);
$imsize = @getimagesize($file);
if ($imsize === FALSE) {
//TODO handle error better.
//values here are consistent with one that should be max size of logo.
return array(60, 30, null, null);
}
}
return $imsize;
}
}
?>

View File

@ -0,0 +1,84 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
require_once dirname(__FILE__) . '/../../../include/tcpdf/config/lang/eng.php';
require_once dirname(__FILE__) . '/../../../include/tcpdf/tcpdf.php';
class Vtiger_PDF_TCPDF extends TCPDF {
protected $FontFamily;
public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8') {
parent::__construct($orientation, $unit, $format, $unicode, $encoding);
$this->SetFont('','',10);
$this->setFontFamily('times');
}
function getFontSize() {
return $this->FontSizePt;
}
function setFontFamily($family) {
$this->FontFamily = $family;
}
function GetStringHeight($sa,$w) {
if(empty($sa)) return 0;
$sa = str_replace("\r","",$sa);
// remove the last newline
if (substr($sa,-1) == "\n")
$sa = substr($sa,0,-1);
$blocks = explode("\n",$sa);
$wmax = $w - (2 * $this->cMargin);
$lines = 0;
$spacesize = $this->GetCharWidth(32);
foreach ($blocks as $block) {
if (!empty($block)) {
$words = explode(" ",$block);
$cw = 0;
for ($i = 0;$i < count($words);$i++) {
if ($i != 0) $cw += $spacesize;
$wordwidth = $this->GetStringWidth($words[$i]);
$cw += $wordwidth;
if ($cw > $wmax) { // linebreak
$cw = $wordwidth;
$lines++;
}
}
}
$lines++;
}
return ($lines * ($this->FontSize * $this->cell_height_ratio)) + 2;
}
function SetFont($family, $style='', $size='') {
if($family == '') {
$family = $this->FontFamily;
}
//Select a font; size given in points
if ($size == 0) {
$size = $this->FontSizePt;
}
// try to add font (if not already added)
$fontdata = $this->AddFont($family, $style);
$this->FontFamily = $fontdata['family'];
$this->FontStyle = $fontdata['style'];
$this->CurrentFont = &$this->fonts[$fontdata['fontkey']];
$this->SetFontSize($size);
}
}
?>

View File

@ -0,0 +1,204 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../viewers/ContentViewer.php';
class Vtiger_PDF_InventoryContentViewer extends Vtiger_PDF_ContentViewer {
protected $headerRowHeight = 8;
protected $onSummaryPage = false;
function __construct() {
// NOTE: General A4 PDF width ~ 189 (excluding margins on either side)
$this->cells = array( // Name => Width
'Code' => 30,
'Name' => 55,
'Quantity'=> 20,
'Price' => 20,
'Discount'=> 19,
'Tax' => 16,
'Total' => 30
);
}
function initDisplay($parent) {
$pdf = $parent->getPDF();
$contentFrame = $parent->getContentFrame();
$pdf->MultiCell($contentFrame->w, $contentFrame->h, "", 1, 'L', 0, 1, $contentFrame->x, $contentFrame->y);
// Defer drawing the cell border later.
if(!$parent->onLastPage()) {
$this->displayWatermark($parent);
}
// Header
$offsetX = 0;
$pdf->SetFont('','B');
foreach($this->cells as $cellName => $cellWidth) {
$cellLabel = ($this->labelModel)? $this->labelModel->get($cellName, $cellName) : $cellName;
$pdf->MultiCell($cellWidth, $this->headerRowHeight, $cellLabel, 1, 'L', 0, 1, $contentFrame->x+$offsetX, $contentFrame->y);
$offsetX += $cellWidth;
}
$pdf->SetFont('','');
// Reset the y to use
$contentFrame->y += $this->headerRowHeight;
}
function drawCellBorder($parent, $cellHeights=False) {
$pdf = $parent->getPDF();
$contentFrame = $parent->getContentFrame();
if(empty($cellHeights)) $cellHeights = array();
$offsetX = 0;
foreach($this->cells as $cellName => $cellWidth) {
$cellHeight = isset($cellHeights[$cellName])? $cellHeights[$cellName] : $contentFrame->h;
$offsetY = $contentFrame->y-$this->headerRowHeight;
$pdf->MultiCell($cellWidth, $cellHeight, "", 1, 'L', 0, 1, $contentFrame->x+$offsetX, $offsetY);
$offsetX += $cellWidth;
}
}
function display($parent) {
$this->displayPreLastPage($parent);
$this->displayLastPage($parent);
}
function displayPreLastPage($parent) {
$models = $this->contentModels;
$totalModels = count($models);
$pdf = $parent->getPDF();
$parent->createPage();
$contentFrame = $parent->getContentFrame();
$contentLineX = $contentFrame->x; $contentLineY = $contentFrame->y;
$overflowOffsetH = 8; // This is offset used to detect overflow to next page
for ($index = 0; $index < $totalModels; ++$index) {
$model = $models[$index];
$contentHeight = 1;
// Determine the content height to use
foreach($this->cells as $cellName => $cellWidth) {
$contentString = $model->get($cellName);
if(empty($contentString)) continue;
$contentStringHeight = $pdf->GetStringHeight($contentString, $cellWidth);
if ($contentStringHeight > $contentHeight) $contentHeight = $contentStringHeight;
}
// Are we overshooting the height?
if(ceil($contentLineY + $contentHeight) > ceil($contentFrame->h+$contentFrame->y)) {
$this->drawCellBorder($parent);
$parent->createPage();
$contentFrame = $parent->getContentFrame();
$contentLineX = $contentFrame->x; $contentLineY = $contentFrame->y;
}
$offsetX = 0;
foreach($this->cells as $cellName => $cellWidth) {
$pdf->MultiCell($cellWidth, $contentHeight, $model->get($cellName), 0, 'L', 0, 1, $contentLineX+$offsetX, $contentLineY);
$offsetX += $cellWidth;
}
$contentLineY = $pdf->GetY();
$commentContent = $model->get('Comment');
if (!empty($commentContent)) {
$commentCellWidth = $this->cells['Name'];
$offsetX = $this->cells['Code'];
$contentHeight = $pdf->GetStringHeight($commentContent, $commentCellWidth);
if(ceil($contentLineY + $contentHeight + $overflowOffsetH) > ceil($contentFrame->h+$contentFrame->y)) {
$this->drawCellBorder($parent);
$parent->createPage();
$contentFrame = $parent->getContentFrame();
$contentLineX = $contentFrame->x; $contentLineY = $contentFrame->y;
}
$pdf->MultiCell($commentCellWidth, $contentHeight, $model->get('Comment'), 0, 'L', 0, 1, $contentLineX+$offsetX,
$contentLineY);
$contentLineY = $pdf->GetY();
}
}
// Summary
$cellHeights = array();
if ($this->contentSummaryModel) {
$summaryCellKeys = $this->contentSummaryModel->keys(); $summaryCellCount = count($summaryCellKeys);
$summaryCellLabelWidth = $this->cells['Quantity'] + $this->cells['Price'] + $this->cells['Discount'] + $this->cells['Tax'];
$summaryCellHeight = $pdf->GetStringHeight("TEST", $summaryCellLabelWidth); // Pre-calculate cell height
$summaryTotalHeight = ceil(($summaryCellHeight * $summaryCellCount));
if (($contentFrame->h+$contentFrame->y) - ($contentLineY+$overflowOffsetH) < $summaryTotalHeight) { //$overflowOffsetH is added so that last Line Item is not overlapping
$this->drawCellBorder($parent);
$parent->createPage();
$contentFrame = $parent->getContentFrame();
$contentLineX = $contentFrame->x; $contentLineY = $contentFrame->y;
}
$summaryLineX = $contentLineX + $this->cells['Code'] + $this->cells['Name'];
$summaryLineY = ($contentFrame->h+$contentFrame->y-$this->headerRowHeight)-$summaryTotalHeight;
foreach($summaryCellKeys as $key) {
$pdf->MultiCell($summaryCellLabelWidth, $summaryCellHeight, $key, 1, 'L', 0, 1, $summaryLineX, $summaryLineY);
$pdf->MultiCell($contentFrame->w-$summaryLineX+10-$summaryCellLabelWidth, $summaryCellHeight,
$this->contentSummaryModel->get($key), 1, 'R', 0, 1, $summaryLineX+$summaryCellLabelWidth, $summaryLineY);
$summaryLineY = $pdf->GetY();
}
$cellIndex = 0;
foreach($this->cells as $cellName=>$cellWidth) {
if ($cellIndex < 2) $cellHeights[$cellName] = $contentFrame->h;
else $cellHeights[$cellName] = $contentFrame->h - $summaryTotalHeight;
++$cellIndex;
}
}
$this->onSummaryPage = true;
$this->drawCellBorder($parent, $cellHeights);
}
function displayLastPage($parent) {
// Add last page to take care of footer display
if($parent->createLastPage()) {
$this->onSummaryPage = false;
}
}
function drawStatusWaterMark($parent) {
$pdf = $parent->getPDF();
$waterMarkPositions=array("30","180");
$waterMarkRotate=array("45","50","180");
$pdf->SetFont('Arial','B',50);
$pdf->SetTextColor(230,230,230);
$pdf->Rotate($waterMarkRotate[0], $waterMarkRotate[1], $waterMarkRotate[2]);
$pdf->Text($waterMarkPositions[0], $waterMarkPositions[1], 'created');
$pdf->Rotate(0);
$pdf->SetTextColor(0,0,0);
}
}

View File

@ -0,0 +1,27 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/ContentViewer.php';
class Vtiger_PDF_InventoryTaxGroupContentViewer extends Vtiger_PDF_InventoryContentViewer {
function __construct() {
// NOTE: General A4 PDF width ~ 189 (excluding margins on either side)
$this->cells = array( // Name => Width
'Code' => 30,
'Name' => 65,
'Quantity' => 20,
'Price' => 25,
'Discount' => 20,
'Total' => 30
);
}
}

View File

@ -0,0 +1,68 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../viewers/FooterViewer.php';
class Vtiger_PDF_InventoryFooterViewer extends Vtiger_PDF_FooterViewer {
static $DESCRIPTION_DATA_KEY = '__DES__DATA__';
static $TERMSANDCONDITION_DATA_KEY = '__TANDC__DATA__';
static $DESCRIPTION_LABEL_KEY = '__DES_LABEL__';
static $TERMSANDCONDITION_LABEL_KEY = '__TANDC_LABEL__';
function totalHeight($parent) {
if($this->model && $this->onEveryPage()) {
$pdf = $parent->getPDF();
$footerTitleHeight = 8.0;
$termsConditionText = $this->model->get(self::$TERMSANDCONDITION_DATA_KEY);
$termsConditionHeight = $pdf->GetStringHeight($termsConditionText, $parent->getTotalWidth());
if($termsConditionHeight) $termsConditionHeight += $footerTitleHeight;
$descriptionText = $this->model->get(self::$DESCRIPTION_DATA_KEY);
$descriptionHeight = $pdf->GetStringHeight($descriptionText, $parent->getTotalWidth());
if($descriptionHeight) $descriptionHeight += $footerTitleHeight;
return $termsConditionHeight + $descriptionHeight;
}
return parent::totalHeight($parent);
}
function display($parent) {
$pdf = $parent->getPDF();
$footerFrame = $parent->getFooterFrame();
if($this->model) {
$targetFooterHeight = ($this->onEveryPage())? $footerFrame->h : 0;
$descriptionString = $this->labelModel->get(self::$DESCRIPTION_LABEL_KEY);
$description = $this->model->get(self::$DESCRIPTION_DATA_KEY);
$descriptionHeight = $pdf->GetStringHeight($descriptionString, $footerFrame->w);
$pdf->SetFillColor(205,201,201);
$pdf->MultiCell($footerFrame->w, $descriptionHeight, $descriptionString, 1, 'L', 1, 1, $footerFrame->x, $footerFrame->y);
$pdf->MultiCell($footerFrame->w, $targetFooterHeight - $descriptionHeight, $description, 1, 'L',
0, 1, $footerFrame->x, $footerFrame->y + $descriptionHeight);
$termsAndConditionLabelString = $this->labelModel->get(self::$TERMSANDCONDITION_LABEL_KEY);
$termsAndCondition = $this->model->get(self::$TERMSANDCONDITION_DATA_KEY);
$offsetY = 2.0;
$termsAndConditionHeight = $pdf->GetStringHeight($termsAndConditionLabelString, $footerFrame->w);
$pdf->SetFillColor(205,201,201);
$pdf->MultiCell($footerFrame->w, $termsAndConditionHeight, $termsAndConditionLabelString, 1, 'L', 1, 1,
$pdf->GetX(), $pdf->GetY() + $offsetY);
$pdf->MultiCell($footerFrame->w, $targetFooterHeight - $termsAndConditionHeight, $termsAndCondition,1, 'L', 0, 1,
$pdf->GetX(), $pdf->GetY());
}
}
}
?>

View File

@ -0,0 +1,129 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/../viewers/HeaderViewer.php';
class Vtiger_PDF_InventoryHeaderViewer extends Vtiger_PDF_HeaderViewer {
function totalHeight($parent) {
$height = 85;
if($this->onEveryPage) return $height;
if($this->onFirstPage && $parent->onFirstPage()) $height;
return 0;
}
function display($parent) {
$pdf = $parent->getPDF();
$headerFrame = $parent->getHeaderFrame();
if($this->model) {
$headerColumnWidth = $headerFrame->w/3.0;
$modelColumns = $this->model->get('columns');
// Column 1
$offsetX = 5;
$modelColumn0 = $modelColumns[0];
list($imageWidth, $imageHeight, $imageType, $imageAttr) = $parent->getimagesize(
$modelColumn0['logo']);
//division because of mm to px conversion
$w = $imageWidth/3;
if($w > 60) {
$w=60;
}
$h = $imageHeight/3;
if($h > 30) {
$h = 30;
}
$pdf->Image($modelColumn0['logo'], $headerFrame->x, $headerFrame->y, $w, $h);
$imageHeightInMM = 30;
$pdf->SetFont('', 'B');
$contentHeight = $pdf->GetStringHeight( $modelColumn0['summary'], $headerColumnWidth);
$pdf->MultiCell($headerColumnWidth, $contentHeight, $modelColumn0['summary'], 0, 'L', 0, 1,
$headerFrame->x, $headerFrame->y+$imageHeightInMM+2);
$pdf->SetFont('', '');
$contentHeight = $pdf->GetStringHeight( $modelColumn0['content'], $headerColumnWidth);
$pdf->MultiCell($headerColumnWidth, $contentHeight, $modelColumn0['content'], 0, 'L', 0, 1,
$headerFrame->x, $pdf->GetY());
// Column 2
$offsetX = 5;
$pdf->SetY($headerFrame->y);
$modelColumn1 = $modelColumns[1];
$offsetY = 8;
foreach($modelColumn1 as $label => $value) {
if(!empty($value)) {
$pdf->SetFont('', 'B');
$pdf->SetFillColor(205,201,201);
$pdf->MultiCell($headerColumnWidth-$offsetX, 7, $label, 1, 'C', 1, 1, $headerFrame->x+$headerColumnWidth+$offsetX, $pdf->GetY()+$offsetY);
$pdf->SetFont('', '');
$pdf->MultiCell($headerColumnWidth-$offsetX, 7, $value, 1, 'C', 0, 1, $headerFrame->x+$headerColumnWidth+$offsetX, $pdf->GetY());
$offsetY = 2;
}
}
// Column 3
$offsetX = 10;
$modelColumn2 = $modelColumns[2];
$contentWidth = $pdf->GetStringWidth($this->model->get('title'));
$contentHeight = $pdf->GetStringHeight($this->model->get('title'), $contentWidth);
$roundedRectX = $headerFrame->w+$headerFrame->x-$contentWidth*2.0;
$roundedRectW = $contentWidth*2.0;
$pdf->RoundedRect($roundedRectX, 10, $roundedRectW, 10, 3, '1111', 'DF', array(), array(205,201,201));
$contentX = $roundedRectX + (($roundedRectW - $contentWidth)/2.0);
$pdf->SetFont('', 'B');
$pdf->MultiCell($contentWidth*2.0, $contentHeight, $this->model->get('title'), 0, 'R', 0, 1, $contentX-$contentWidth,
$headerFrame->y+1);
$offsetY = 2;
foreach($modelColumn2 as $label => $value) {
if(is_array($value)) {
$pdf->SetFont('', '');
foreach($value as $l => $v) {
$pdf->MultiCell($headerColumnWidth-$offsetX, 7, sprintf('%s: %s', $l, $v), 1, 'C', 0, 1,
$headerFrame->x+$headerColumnWidth*2.0+$offsetX, $pdf->GetY()+$offsetY);
$offsetY = 0;
}
} else {
$offsetY = 1;
$pdf->SetFont('', 'B');
$pdf->SetFillColor(205,201,201);
$pdf->MultiCell($headerColumnWidth-$offsetX, 7, $label, 1, 'L', 1, 1, $headerFrame->x+$headerColumnWidth*2.0+$offsetX,
$pdf->GetY()+$offsetY);
$pdf->SetFont('', '');
$pdf->MultiCell($headerColumnWidth-$offsetX, 7, $value, 1, 'L', 0, 1, $headerFrame->x+$headerColumnWidth*2.0+$offsetX,
$pdf->GetY());
}
}
$pdf->setFont('', '');
// Add the border cell at the end
// This is required to reset Y position for next write
$pdf->MultiCell($headerFrame->w, $headerFrame->h-$headerFrame->y, "", 0, 'L', 0, 1, $headerFrame->x, $headerFrame->y);
}
}
}

View File

@ -0,0 +1,28 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
class Vtiger_PDF_Model {
protected $values = array();
function set($key, $value) {
$this->values[$key] = $value;
}
function get($key, $defvalue='') {
return (isset($this->values[$key]))? $this->values[$key] : $defvalue;
}
function count() {
return count($this->values);
}
function keys() {
return array_keys($this->values);
}
}

View File

@ -0,0 +1,100 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/Viewer.php';
class Vtiger_PDF_ContentViewer extends Vtiger_PDF_Viewer {
protected $cells;
protected $contentModels = array();
protected $contentSummaryModel;
protected $watermarkModel;
function addContentModel($m) {
$this->contentModels[] = $m;
}
function setContentModels($m) {
if(!is_array($m)) $m = array($m);
$this->contentModels = $m;
}
function setSummaryModel($m) {
$this->contentSummaryModel = $m;
}
function setWatermarkModel($m) {
$this->watermarkModel = $m;
}
function totalHeight($parent) {
return 0; // Variable height
}
function initDisplay($parent) {
$pdf = $parent->getPDF();
$contentFrame = $parent->getContentFrame();
$pdf->MultiCell($contentFrame->w, $contentFrame->h, "", 1, 'L', 0, 1, $contentFrame->x, $contentFrame->y);
}
function displayWatermark($parent) {
$pdf = $parent->getPDF();
$contentFrame = $parent->getContentFrame();
if($this->watermarkModel) {
$content = $this->watermarkModel->get('content');
$currentFontSize = $pdf->getFontSize();
$pdf->SetFont('','B',40);
$pdf->SetTextColor(240,240,240);
$contentW = $pdf->GetStringWidth($content);
$contentH = $pdf->GetStringHeight($content, $contentFrame->w);
$contentLineY = $contentFrame->y + ($contentFrame->h/2.0) - ($contentH/2.0);
$contentLineX = $contentFrame->x + ($contentFrame->w/2.0) - ($contentW/2.0);
$pdf->Text($contentLineX, $contentLineY, $content);
$pdf->SetTextColor(0,0,0);
$pdf->SetFont('','',$currentFontSize);
}
}
function display($parent) {
$models = $this->contentModels;
$totalModels = count($models);
$pdf = $parent->getPDF();
$parent->createPage();
$contentFrame = $parent->getContentFrame();
$contentLineX = $contentFrame->x; $contentLineY = $contentFrame->y;
for ($index = 0; $index < $totalModels; ++$index) {
$model = $models[$index];
$contentHeight = $pdf->GetStringHeight($model->get('content'), $contentFrame->w);
if($contentLineY + $contentHeight > ($contentFrame->h+$contentFrame->y)) {
$parent->createPage();
$contentFrame = $parent->getContentFrame();
$contentLineX = $contentFrame->x; $contentLineY = $contentFrame->y;
}
$pdf->MultiCell($contentFrame->w, $contentHeight, $model->get('content'), 1, 'L', 0, 1, $contentLineX, $contentLineY);
$contentLineY = $pdf->GetY();
}
// Add last page to take care of footer display
$parent->createLastPage();
}
}

View File

@ -0,0 +1,73 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/Viewer.php';
class Vtiger_PDF_FooterViewer extends Vtiger_PDF_Viewer {
protected $model;
protected $onEveryPage = true;
protected $onLastPage = false;
function setOnEveryPage() {
$this->onEveryPage = true;
$this->onLastPage = false;
}
function onEveryPage() {
return $this->onEveryPage;
}
function setOnLastPage() {
$this->onEveryPage = false;
$this->onLastPage = true;
}
function onLastPage() {
return $this->onLastPage;
}
function setModel($m) {
$this->model = $m;
}
function totalHeight($parent) {
$height = 0.1;
if($this->model && $this->onEveryPage()) {
$pdf = $parent->getPDF();
$contentText = $this->model->get('content');
$height = $pdf->GetStringHeight($contentText, $parent->getTotalWidth());
}
if($this->onEveryPage) return $height;
if($this->onLastPage && $parent->onLastPage()) return $height;
return 0;
}
function initDisplay($parent) {
}
function display($parent) {
$pdf = $parent->getPDF();
$footerFrame = $parent->getFooterFrame();
if($this->model) {
$targetFooterHeight = ($this->onEveryPage())? $footerFrame->h : 0;
$pdf->MultiCell($footerFrame->w, $targetFooterHeight, $this->model->get('content'), 1, 'L', 0, 1, $footerFrame->x, $footerFrame->y);
}
}
}

View File

@ -0,0 +1,73 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/Viewer.php';
class Vtiger_PDF_HeaderViewer extends Vtiger_PDF_Viewer {
protected $model;
protected $onEveryPage = true;
protected $onFirstPage = false;
function setOnEveryPage() {
$this->onEveryPage = true;
$this->onLastPage = false;
}
function onEveryPage() {
$this->onEveryPage = true;
$this->onLastPage = false;
}
function setOnFirstPage() {
$this->onEveryPage = false;
$this->onLastPage = true;
}
function onFirstPage() {
$this->onEveryPage = false;
$this->onLastPage = true;
}
function setModel($m) {
$this->model = $m;
}
function totalHeight($parent) {
$height = 10;
if($this->model && $this->onEveryPage()) {
$pdf = $parent->getPDF();
$contentText = $this->model->get('content');
$height = $pdf->GetStringHeight($contentText, $parent->getTotalWidth());
}
if($this->onEveryPage) return $height;
if($this->onFirstPage && $parent->onFirstPage()) $height;
return 0;
}
function initDisplay($parent) {
$pdf = $parent->getPDF();
$headerFrame = $parent->getHeaderFrame();
}
function display($parent) {
$pdf = $parent->getPDF();
$headerFrame = $parent->getHeaderFrame();
if($this->model) {
$pdf->MultiCell($headerFrame->w, $headerFrame->h, $this->model->get('content'), 1, 'L', 0, 1, $headerFrame->x, $headerFrame->y);
}
}
}

View File

@ -0,0 +1,41 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once dirname(__FILE__) . '/Viewer.php';
class Vtiger_PDF_PagerViewer extends Vtiger_PDF_Viewer {
protected $model;
function setModel($m) {
$this->model = $m;
}
function totalHeight($parent) {
return 10;
}
function initDisplay($parent) {
}
function display($parent) {
$pdf = $parent->getPDF();
$headerFrame = $parent->getHeaderFrame();
$displayFormat = '-%s-';
if($this->model) {
$displayFormat = $this->model->get('format', $displayFormat);
}
$contentHeight = $pdf->GetStringHeight($displayFormat, $headerFrame->w/2.0);
$pdf->MultiCell($headerFrame->w/2.0, $contentHeight, sprintf($displayFormat, $pdf->getPage()), 0, 'L', 0, 1,
$headerFrame->x+$headerFrame->w/2.0, $headerFrame->y);
}
}
?>

View File

@ -0,0 +1,21 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
abstract class Vtiger_PDF_Viewer {
protected $labelModel;
function setLabelModel($m) {
$this->labelModel = $m;
}
abstract function totalHeight($parent);
abstract function initDisplay($parent);
abstract function display($parent);
}

View File

@ -0,0 +1,739 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once('vtlib/Vtiger/PackageExport.php');
include_once('vtlib/Vtiger/Unzip.php');
include_once('vtlib/Vtiger/Module.php');
include_once('vtlib/Vtiger/Event.php');
include_once('vtlib/Vtiger/Cron.php');
/**
* Provides API to import module into vtiger CRM
* @package vtlib
*/
class Vtiger_PackageImport extends Vtiger_PackageExport {
/**
* Module Meta XML File (Parsed)
* @access private
*/
var $_modulexml;
/**
* Module Fields mapped by [modulename][fieldname] which
* will be used to create customviews.
* @access private
*/
var $_modulefields_cache = Array();
/**
* License of the package.
* @access private
*/
var $_licensetext = false;
/**
* Constructor
*/
function Vtiger_PackageImport() {
parent::__construct();
}
/**
* Parse the manifest file
* @access private
*/
function __parseManifestFile($unzip) {
$manifestfile = $this->__getManifestFilePath();
$unzip->unzip('manifest.xml', $manifestfile);
$this->_modulexml = simplexml_load_file($manifestfile);
unlink($manifestfile);
}
/**
* Get type of package (as specified in manifest)
*/
function type() {
if(!empty($this->_modulexml) && !empty($this->_modulexml->type)) {
return $this->_modulexml->type;
}
return false;
}
/**
* XPath evaluation on the root module node.
* @param String Path expression
*/
function xpath($path) {
return $this->_modulexml->xpath($path);
}
/**
* Get the value of matching path (instead of complete xpath result)
* @param String Path expression for which value is required
*/
function xpath_value($path) {
$xpathres = $this->xpath($path);
foreach($xpathres as $pathkey=>$pathvalue) {
if($pathkey == $path) return $pathvalue;
}
return false;
}
/**
* Are we trying to import language package?
*/
function isLanguageType($zipfile =null) {
if(!empty($zipfile)) {
if(!$this->checkZip($zipfile)) {
return false;
}
}
$packagetype = $this->type();
if($packagetype) {
$lcasetype = strtolower($packagetype);
if($lcasetype == 'language') return true;
}
return false;
}
/**
* checks whether a package is module bundle or not.
* @param String $zipfile - path to the zip file.
* @return Boolean - true if given zipfile is a module bundle and false otherwise.
*/
function isModuleBundle($zipfile = null) {
// If data is not yet available
if(!empty($zipfile)) {
if(!$this->checkZip($zipfile)) {
return false;
}
}
return (boolean)$this->_modulexml->modulebundle;
}
/**
* @return Array module list available in the module bundle.
*/
function getAvailableModuleInfoFromModuleBundle() {
$list = (Array)$this->_modulexml->modulelist;
return (Array)$list['dependent_module'];
}
/**
* Get the license of this package
* NOTE: checkzip should have been called earlier.
*/
function getLicense() {
return $this->_licensetext;
}
/**
* Check if zipfile is a valid package
* @access private
*/
function checkZip($zipfile) {
$unzip = new Vtiger_Unzip($zipfile);
$filelist = $unzip->getList();
$manifestxml_found = false;
$languagefile_found = false;
$vtigerversion_found = false;
$modulename = null;
$language_modulename = null;
foreach($filelist as $filename=>$fileinfo) {
$matches = Array();
preg_match('/manifest.xml/', $filename, $matches);
if(count($matches)) {
$manifestxml_found = true;
$this->__parseManifestFile($unzip);
$modulename = $this->_modulexml->name;
$isModuleBundle = (string)$this->_modulexml->modulebundle;
if($isModuleBundle === 'true' && (!empty($this->_modulexml)) &&
(!empty($this->_modulexml->dependencies)) &&
(!empty($this->_modulexml->dependencies->vtiger_version))) {
$languagefile_found = true;
break;
}
// Do we need to check the zip further?
if($this->isLanguageType()) {
$languagefile_found = true; // No need to search for module language file.
break;
} else {
continue;
}
}
// Check for language file.
preg_match("/modules\/([^\/]+)\/language\/en_us.lang.php/", $filename, $matches);
if(count($matches)) { $language_modulename = $matches[1]; continue; }
}
// Verify module language file.
if(!empty($language_modulename) && $language_modulename == $modulename) {
$languagefile_found = true;
}
if(!empty($this->_modulexml) &&
!empty($this->_modulexml->dependencies) &&
!empty($this->_modulexml->dependencies->vtiger_version)) {
$vtigerversion_found = true;
}
$validzip = false;
if($manifestxml_found && $languagefile_found && $vtigerversion_found)
$validzip = true;
if($validzip) {
if(!empty($this->_modulexml->license)) {
if(!empty($this->_modulexml->license->inline)) {
$this->_licensetext = $this->_modulexml->license->inline;
} else if(!empty($this->_modulexml->license->file)) {
$licensefile = $this->_modulexml->license->file;
$licensefile = "$licensefile";
if(!empty($filelist[$licensefile])) {
$this->_licensetext = $unzip->unzip($licensefile);
} else {
$this->_licensetext = "Missing $licensefile!";
}
}
}
}
if($unzip) $unzip->close();
return $validzip;
}
/**
* Get module name packaged in the zip file
* @access private
*/
function getModuleNameFromZip($zipfile) {
if(!$this->checkZip($zipfile)) return null;
return (string)$this->_modulexml->name;
}
/**
* returns the name of the module.
* @return String - name of the module as given in manifest file.
*/
function getModuleName() {
return (string)$this->_modulexml->name;
}
/**
* Cache the field instance for re-use
* @access private
*/
function __AddModuleFieldToCache($moduleInstance, $fieldname, $fieldInstance) {
$this->_modulefields_cache["$moduleInstance->name"]["$fieldname"] = $fieldInstance;
}
/**
* Get field instance from cache
* @access private
*/
function __GetModuleFieldFromCache($moduleInstance, $fieldname) {
return $this->_modulefields_cache["$moduleInstance->name"]["$fieldname"];
}
/**
* Initialize Import
* @access private
*/
function initImport($zipfile, $overwrite) {
$module = $this->getModuleNameFromZip($zipfile);
if($module != null) {
$unzip = new Vtiger_Unzip($zipfile, $overwrite);
// Unzip selectively
$unzip->unzipAllEx( ".",
Array(
// Include only file/folders that need to be extracted
'include' => Array('templates', "modules/$module", 'cron'),
//'exclude' => Array('manifest.xml')
// NOTE: If excludes is not given then by those not mentioned in include are ignored.
),
// What files needs to be renamed?
Array(
// Templates folder
'templates' => "Smarty/templates/modules/$module",
// Cron folder
'cron' => "cron/modules/$module"
)
);
if($unzip) $unzip->close();
}
return $module;
}
function getTemporaryFilePath($filepath=false) {
return 'cache/'. $filepath;
}
/**
* Get dependent version
* @access private
*/
function getDependentVtigerVersion() {
return $this->_modulexml->dependencies->vtiger_version;
}
/**
* Get dependent Maximum version
* @access private
*/
function getDependentMaxVtigerVersion() {
return $this->_modulexml->dependencies->vtiger_max_version;
}
/**
* Get package version
* @access private
*/
function getVersion() {
return $this->_modulexml->version;
}
/**
* Import Module from zip file
* @param String Zip file name
* @param Boolean True for overwriting existing module
*
* @todo overwrite feature is not functionally currently.
*/
function import($zipfile, $overwrite=false) {
$module = $this->getModuleNameFromZip($zipfile);
if($module != null) {
// If data is not yet available
if(empty($this->_modulexml)) {
$this->__parseManifestFile($unzip);
}
$buildModuleArray = array();
$installSequenceArray = array();
$moduleBundle = (boolean)$this->_modulexml->modulebundle;
if($moduleBundle == true) {
$moduleList = (Array)$this->_modulexml->modulelist;
foreach($moduleList as $moduleInfos) {
foreach($moduleInfos as $moduleInfo) {
$moduleInfo = (Array)$moduleInfo;
$buildModuleArray[] = $moduleInfo;
$installSequenceArray[] = $moduleInfo['install_sequence'];
}
}
sort($installSequenceArray);
$unzip = new Vtiger_Unzip($zipfile);
$unzip->unzipAllEx($this->getTemporaryFilePath());
foreach ($installSequenceArray as $sequence) {
foreach ($buildModuleArray as $moduleInfo) {
if($moduleInfo['install_sequence'] == $sequence) {
$this->import($this->getTemporaryFilePath($moduleInfo['filepath']), $overwrite);
}
}
}
} else {
$module = $this->initImport($zipfile, $overwrite);
// Call module import function
$this->import_Module();
}
}
}
/**
* Import Module
* @access private
*/
function import_Module() {
$tabname = $this->_modulexml->name;
$tablabel= $this->_modulexml->label;
$parenttab=(string)$this->_modulexml->parent;
$tabversion=$this->_modulexml->version;
$isextension= false;
if(!empty($this->_modulexml->type)) {
$type = strtolower($this->_modulexml->type);
if($type == 'extension' || $type == 'language')
$isextension = true;
}
$vtigerMinVersion = $this->_modulexml->dependencies->vtiger_version;
$vtigerMaxVersion = $this->_modulexml->dependencies->vtiger_max_version;
$moduleInstance = new Vtiger_Module();
$moduleInstance->name = $tabname;
$moduleInstance->label= $tablabel;
$moduleInstance->parent=$parenttab;
$moduleInstance->isentitytype = ($isextension != true);
$moduleInstance->version = (!$tabversion)? 0 : $tabversion;
$moduleInstance->minversion = (!$vtigerMinVersion)? false : $vtigerMinVersion;
$moduleInstance->maxversion = (!$vtigerMaxVersion)? false : $vtigerMaxVersion;
$moduleInstance->save();
if(!empty($parenttab)) {
$menuInstance = Vtiger_Menu::getInstance($parenttab);
$menuInstance->addModule($moduleInstance);
}
$this->import_Tables($this->_modulexml);
$this->import_Blocks($this->_modulexml, $moduleInstance);
$this->import_CustomViews($this->_modulexml, $moduleInstance);
$this->import_SharingAccess($this->_modulexml, $moduleInstance);
$this->import_Events($this->_modulexml, $moduleInstance);
$this->import_Actions($this->_modulexml, $moduleInstance);
$this->import_RelatedLists($this->_modulexml, $moduleInstance);
$this->import_CustomLinks($this->_modulexml, $moduleInstance);
$this->import_CronTasks($this->_modulexml);
Vtiger_Module::fireEvent($moduleInstance->name,
Vtiger_Module::EVENT_MODULE_POSTINSTALL);
$moduleInstance->initWebservice();
}
/**
* Import Tables of the module
* @access private
*/
function import_Tables($modulenode) {
if(empty($modulenode->tables) || empty($modulenode->tables->table)) return;
/**
* Record the changes in schema file
*/
$schemafile = fopen("modules/$modulenode->name/schema.xml", 'w');
if($schemafile) {
fwrite($schemafile, "<?xml version='1.0'?>\n");
fwrite($schemafile, "<schema>\n");
fwrite($schemafile, "\t<tables>\n");
}
// Import the table via queries
foreach($modulenode->tables->table as $tablenode) {
$tablename = $tablenode->name;
$tablesql = "$tablenode->sql"; // Convert to string format
// Save the information in the schema file.
fwrite($schemafile, "\t\t<table>\n");
fwrite($schemafile, "\t\t\t<name>$tablename</name>\n");
fwrite($schemafile, "\t\t\t<sql><![CDATA[$tablesql]]></sql>\n");
fwrite($schemafile, "\t\t</table>\n");
// Avoid executing SQL that will DELETE or DROP table data
if(Vtiger_Utils::IsCreateSql($tablesql)) {
if(!Vtiger_Utils::checkTable($tablename)) {
self::log("SQL: $tablesql ... ", false);
Vtiger_Utils::ExecuteQuery($tablesql);
self::log("DONE");
}
} else {
if(Vtiger_Utils::IsDestructiveSql($tablesql)) {
self::log("SQL: $tablesql ... SKIPPED");
} else {
self::log("SQL: $tablesql ... ", false);
Vtiger_Utils::ExecuteQuery($tablesql);
self::log("DONE");
}
}
}
if($schemafile) {
fwrite($schemafile, "\t</tables>\n");
fwrite($schemafile, "</schema>\n");
fclose($schemafile);
}
}
/**
* Import Blocks of the module
* @access private
*/
function import_Blocks($modulenode, $moduleInstance) {
if(empty($modulenode->blocks) || empty($modulenode->blocks->block)) return;
foreach($modulenode->blocks->block as $blocknode) {
$blockInstance = $this->import_Block($modulenode, $moduleInstance, $blocknode);
$this->import_Fields($blocknode, $blockInstance, $moduleInstance);
}
}
/**
* Import Block of the module
* @access private
*/
function import_Block($modulenode, $moduleInstance, $blocknode) {
$blocklabel = $blocknode->label;
$blockInstance = new Vtiger_Block();
$blockInstance->label = $blocklabel;
$moduleInstance->addBlock($blockInstance);
return $blockInstance;
}
/**
* Import Fields of the module
* @access private
*/
function import_Fields($blocknode, $blockInstance, $moduleInstance) {
if(empty($blocknode->fields) || empty($blocknode->fields->field)) return;
foreach($blocknode->fields->field as $fieldnode) {
$fieldInstance = $this->import_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode);
}
}
/**
* Import Field of the module
* @access private
*/
function import_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode) {
$fieldInstance = new Vtiger_Field();
$fieldInstance->name = $fieldnode->fieldname;
$fieldInstance->label = $fieldnode->fieldlabel;
$fieldInstance->table = $fieldnode->tablename;
$fieldInstance->column = $fieldnode->columnname;
$fieldInstance->uitype = $fieldnode->uitype;
$fieldInstance->generatedtype= $fieldnode->generatedtype;
$fieldInstance->readonly = $fieldnode->readonly;
$fieldInstance->presence = $fieldnode->presence;
$fieldInstance->defaultvalue = $fieldnode->defaultvalue;
$fieldInstance->maximumlength= $fieldnode->maximumlength;
$fieldInstance->sequence = $fieldnode->sequence;
$fieldInstance->quickcreate = $fieldnode->quickcreate;
$fieldInstance->quicksequence= $fieldnode->quickcreatesequence;
$fieldInstance->typeofdata = $fieldnode->typeofdata;
$fieldInstance->displaytype = $fieldnode->displaytype;
$fieldInstance->info_type = $fieldnode->info_type;
if(!empty($fieldnode->helpinfo))
$fieldInstance->helpinfo = $fieldnode->helpinfo;
if(isset($fieldnode->masseditable))
$fieldInstance->masseditable = $fieldnode->masseditable;
if(isset($fieldnode->columntype) && !empty($fieldnode->columntype))
$fieldInstance->columntype = $fieldnode->columntype;
$blockInstance->addField($fieldInstance);
// Set the field as entity identifier if marked.
if(!empty($fieldnode->entityidentifier)) {
$moduleInstance->entityidfield = $fieldnode->entityidentifier->entityidfield;
$moduleInstance->entityidcolumn= $fieldnode->entityidentifier->entityidcolumn;
$moduleInstance->setEntityIdentifier($fieldInstance);
}
// Check picklist values associated with field if any.
if(!empty($fieldnode->picklistvalues) && !empty($fieldnode->picklistvalues->picklistvalue)) {
$picklistvalues = Array();
foreach($fieldnode->picklistvalues->picklistvalue as $picklistvaluenode) {
$picklistvalues[] = $picklistvaluenode;
}
$fieldInstance->setPicklistValues( $picklistvalues );
}
// Check related modules associated with this field
if(!empty($fieldnode->relatedmodules) && !empty($fieldnode->relatedmodules->relatedmodule)) {
$relatedmodules = Array();
foreach($fieldnode->relatedmodules->relatedmodule as $relatedmodulenode) {
$relatedmodules[] = $relatedmodulenode;
}
$fieldInstance->setRelatedModules($relatedmodules);
}
$this->__AddModuleFieldToCache($moduleInstance, $fieldnode->fieldname, $fieldInstance);
return $fieldInstance;
}
/**
* Import Custom views of the module
* @access private
*/
function import_CustomViews($modulenode, $moduleInstance) {
if(empty($modulenode->customviews) || empty($modulenode->customviews->customview)) return;
foreach($modulenode->customviews->customview as $customviewnode) {
$filterInstance = $this->import_CustomView($modulenode, $moduleInstance, $customviewnode);
}
}
/**
* Import Custom View of the module
* @access private
*/
function import_CustomView($modulenode, $moduleInstance, $customviewnode) {
$viewname = $customviewnode->viewname;
$setdefault=$customviewnode->setdefault;
$setmetrics=$customviewnode->setmetrics;
$filterInstance = new Vtiger_Filter();
$filterInstance->name = $viewname;
$filterInstance->isdefault = $setdefault;
$filterInstance->inmetrics = $setmetrics;
$moduleInstance->addFilter($filterInstance);
foreach($customviewnode->fields->field as $fieldnode) {
$fieldInstance = $this->__GetModuleFieldFromCache($moduleInstance, $fieldnode->fieldname);
$filterInstance->addField($fieldInstance, $fieldnode->columnindex);
if(!empty($fieldnode->rules->rule)) {
foreach($fieldnode->rules->rule as $rulenode) {
$filterInstance->addRule($fieldInstance, $rulenode->comparator, $rulenode->value, $rulenode->columnindex);
}
}
}
}
/**
* Import Sharing Access of the module
* @access private
*/
function import_SharingAccess($modulenode, $moduleInstance) {
if(empty($modulenode->sharingaccess)) return;
if(!empty($modulenode->sharingaccess->default)) {
foreach($modulenode->sharingaccess->default as $defaultnode) {
$moduleInstance->setDefaultSharing($defaultnode);
}
}
}
/**
* Import Events of the module
* @access private
*/
function import_Events($modulenode, $moduleInstance) {
if(empty($modulenode->events) || empty($modulenode->events->event)) return;
if(Vtiger_Event::hasSupport()) {
foreach($modulenode->events->event as $eventnode) {
$this->import_Event($modulenode, $moduleInstance, $eventnode);
}
}
}
/**
* Import Event of the module
* @access private
*/
function import_Event($modulenode, $moduleInstance, $eventnode) {
$event_condition = '';
if(!empty($eventnode->condition)) $event_condition = "$eventnode->condition";
Vtiger_Event::register($moduleInstance,
(string)$eventnode->eventname, (string)$eventnode->classname,
(string)$eventnode->filename, (string)$event_condition
);
}
/**
* Import actions of the module
* @access private
*/
function import_Actions($modulenode, $moduleInstance) {
if(empty($modulenode->actions) || empty($modulenode->actions->action)) return;
foreach($modulenode->actions->action as $actionnode) {
$this->import_Action($modulenode, $moduleInstance, $actionnode);
}
}
/**
* Import action of the module
* @access private
*/
function import_Action($modulenode, $moduleInstance, $actionnode) {
$actionstatus = $actionnode->status;
if($actionstatus == 'enabled')
$moduleInstance->enableTools($actionnode->name);
else
$moduleInstance->disableTools($actionnode->name);
}
/**
* Import related lists of the module
* @access private
*/
function import_RelatedLists($modulenode, $moduleInstance) {
if(empty($modulenode->relatedlists) || empty($modulenode->relatedlists->relatedlist)) return;
foreach($modulenode->relatedlists->relatedlist as $relatedlistnode) {
$relModuleInstance = $this->import_Relatedlist($modulenode, $moduleInstance, $relatedlistnode);
}
}
/**
* Import related list of the module.
* @access private
*/
function import_Relatedlist($modulenode, $moduleInstance, $relatedlistnode) {
$relModuleInstance = Vtiger_Module::getInstance($relatedlistnode->relatedmodule);
$label = $relatedlistnode->label;
$actions = false;
if(!empty($relatedlistnode->actions) && !empty($relatedlistnode->actions->action)) {
$actions = Array();
foreach($relatedlistnode->actions->action as $actionnode) {
$actions[] = "$actionnode";
}
}
if($relModuleInstance) {
$moduleInstance->setRelatedList($relModuleInstance, "$label", $actions, "$relatedlistnode->function");
}
return $relModuleInstance;
}
/**
* Import custom links of the module.
* @access private
*/
function import_CustomLinks($modulenode, $moduleInstance) {
if(empty($modulenode->customlinks) || empty($modulenode->customlinks->customlink)) return;
foreach($modulenode->customlinks->customlink as $customlinknode) {
$handlerInfo = null;
if(!empty($customlinknode->handler_path)) {
$handlerInfo = array();
$handlerInfo = array("$customlinknode->handler_path",
"$customlinknode->handler_class",
"$customlinknode->handler");
}
$moduleInstance->addLink(
"$customlinknode->linktype",
"$customlinknode->linklabel",
"$customlinknode->linkurl",
"$customlinknode->linkicon",
"$customlinknode->sequence",
$handlerInfo
);
}
}
/**
* Import cron jobs of the module.
* @access private
*/
function import_CronTasks($modulenode){
if(empty($modulenode->crons) || empty($modulenode->crons->cron)) return;
foreach ($modulenode->crons->cron as $cronTask){
if(empty($cronTask->status)){
$cronTask->status=Vtiger_Cron::$STATUS_ENABLED;
}
if((empty($cronTask->sequence))){
$cronTask->sequence=Vtiger_Cron::nextSequence();
}
Vtiger_Cron::register("$cronTask->name","$cronTask->handler", "$cronTask->frequency", "$modulenode->name","$cronTask->status","$cronTask->sequence","$cronTask->description");
}
}
}
?>

View File

@ -0,0 +1,412 @@
<?php
/*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************/
include_once('vtlib/Vtiger/PackageImport.php');
/**
* Provides API to update module into vtiger CRM
* @package vtlib
*/
class Vtiger_PackageUpdate extends Vtiger_PackageImport {
var $_migrationinfo = false;
/**
* Constructor
*/
function Vtiger_PackageUpdate() {
parent::__construct();
}
/**
* Initialize Update
* @access private
*/
function initUpdate($moduleInstance, $zipfile, $overwrite) {
$module = $this->getModuleNameFromZip($zipfile);
if(!$moduleInstance || $moduleInstance->name != $module) {
self::log('Module name mismatch!');
return false;
}
if($module != null) {
$unzip = new Vtiger_Unzip($zipfile, $overwrite);
// Unzip selectively
$unzip->unzipAllEx( ".",
Array(
'include' => Array('templates', "modules/$module"), // We don't need manifest.xml
//'exclude' => Array('manifest.xml') // DEFAULT: excludes all not in include
),
// Templates folder to be renamed while copying
Array('templates' => "Smarty/templates/modules/$module"),
// Cron folder to be renamed while copying
Array('cron' => "cron/modules/$module")
);
// If data is not yet available
if(empty($this->_modulexml)) {
$this->__parseManifestFile($unzip);
}
if($unzip) $unzip->close();
}
return $module;
}
/**
* Update Module from zip file
* @param Vtiger_Module Instance of the module to update
* @param String Zip file name
* @param Boolean True for overwriting existing module
*/
function update($moduleInstance, $zipfile, $overwrite=true) {
$module = $this->getModuleNameFromZip($zipfile);
if($module != null) {
// If data is not yet available
if(empty($this->_modulexml)) {
$this->__parseManifestFile($unzip);
}
$buildModuleArray = array();
$installSequenceArray = array();
$moduleBundle = (boolean)$this->_modulexml->modulebundle;
if($moduleBundle == true) {
$moduleList = (Array)$this->_modulexml->modulelist;
foreach($moduleList as $moduleInfos) {
foreach($moduleInfos as $moduleInfo) {
$moduleInfo = (Array)$moduleInfo;
$buildModuleArray[] = $moduleInfo;
$installSequenceArray[] = $moduleInfo['install_sequence'];
}
}
sort($installSequenceArray);
$unzip = new Vtiger_Unzip($zipfile);
$unzip->unzipAllEx($this->getTemporaryFilePath());
foreach ($installSequenceArray as $sequence) {
foreach ($buildModuleArray as $moduleInfo) {
if($moduleInfo['install_sequence'] == $sequence) {
$moduleInstance = Vtiger_Module::getInstance($moduleInfo['name']);
$this->update($moduleInstance, $this->getTemporaryFilePath($moduleInfo['filepath']), $overwrite);
}
}
}
} else {
if(!$moduleInstance || $moduleInstance->name != $module) {
self::log('Module name mismatch!');
return false;
}
$module = $this->initUpdate($moduleInstance, $zipfile, $overwrite);
// Call module update function
$this->update_Module($moduleInstance);
}
}
}
/**
* Update Module
* @access private
*/
function update_Module($moduleInstance) {
$tabname = $this->_modulexml->name;
$tablabel= $this->_modulexml->label;
$parenttab=$this->_modulexml->parent;
$tabversion=$this->_modulexml->version;
$isextension= false;
if(!empty($this->_modulexml->type)) {
$type = strtolower($this->_modulexml->type);
if($type == 'extension' || $type == 'language')
$isextension = true;
}
Vtiger_Module::fireEvent($moduleInstance->name,
Vtiger_Module::EVENT_MODULE_PREUPDATE);
// TODO Handle module property changes like menu, label etc...
/*if(!empty($parenttab) && $parenttab != '') {
$menuInstance = Vtiger_Menu::getInstance($parenttab);
$menuInstance->addModule($moduleInstance);
}*/
$this->handle_Migration($this->_modulexml, $moduleInstance);
$this->update_Tables($this->_modulexml);
$this->update_Blocks($this->_modulexml, $moduleInstance);
$this->update_CustomViews($this->_modulexml, $moduleInstance);
$this->update_SharingAccess($this->_modulexml, $moduleInstance);
$this->update_Events($this->_modulexml, $moduleInstance);
$this->update_Actions($this->_modulexml, $moduleInstance);
$this->update_RelatedLists($this->_modulexml, $moduleInstance);
$this->update_CustomLinks($this->_modulexml, $moduleInstance);
$this->update_CronTasks($this->_modulexml);
$moduleInstance->__updateVersion($tabversion);
Vtiger_Module::fireEvent($moduleInstance->name,
Vtiger_Module::EVENT_MODULE_POSTUPDATE);
}
/**
* Parse migration information from manifest
* @access private
*/
function parse_Migration($modulenode) {
if(!$this->_migrations) {
$this->_migrations = Array();
if(!empty($modulenode->migrations) &&
!empty($modulenode->migrations->migration)) {
foreach($modulenode->migrations->migration as $migrationnode) {
$migrationattrs = $migrationnode->attributes();
$migrationversion = $migrationattrs['version'];
$this->_migrations["$migrationversion"] = $migrationnode;
}
}
// Sort the migration details based on version
if(count($this->_migrations) > 1) {
uksort($this->_migrations, 'version_compare');
}
}
}
/**
* Handle migration of the module
* @access private
*/
function handle_Migration($modulenode, $moduleInstance) {
// TODO Handle module migration SQL
$this->parse_Migration($modulenode);
$cur_version = $moduleInstance->version;
foreach($this->_migrations as $migversion=>$migrationnode) {
// Perform migration only for higher version than current
if(version_compare($cur_version, $migversion, '<')) {
self::log("Migrating to $migversion ... STARTED");
if(!empty($migrationnode->tables) && !empty($migrationnode->tables->table)) {
foreach($migrationnode->tables->table as $tablenode) {
$tablename = $tablenode->name;
$tablesql = "$tablenode->sql"; // Convert to string
// Skip SQL which are destructive
if(Vtiger_Utils::IsDestructiveSql($tablesql)) {
self::log("SQL: $tablesql ... SKIPPED");
} else {
// Supress any SQL query failures
self::log("SQL: $tablesql ... ", false);
Vtiger_Utils::ExecuteQuery($tablesql, true);
self::log("DONE");
}
}
}
self::log("Migrating to $migversion ... DONE");
}
}
}
/**
* Update Tables of the module
* @access private
*/
function update_Tables($modulenode) {
$this->import_Tables($modulenode);
}
/**
* Update Blocks of the module
* @access private
*/
function update_Blocks($modulenode, $moduleInstance) {
if(empty($modulenode->blocks) || empty($modulenode->blocks->block)) return;
foreach($modulenode->blocks->block as $blocknode) {
$blockInstance = Vtiger_Block::getInstance($blocknode->label, $moduleInstance);
if(!$blockInstance) {
$blockInstance = $this->import_Block($modulenode, $moduleInstance, $blocknode);
} else {
$this->update_Block($modulenode, $moduleInstance, $blocknode, $blockInstance);
}
$this->update_Fields($blocknode, $blockInstance, $moduleInstance);
}
}
/**
* Update Block of the module
* @access private
*/
function update_Block($modulenode, $moduleInstance, $blocknode, $blockInstance) {
// TODO Handle block property update
}
/**
* Update Fields of the module
* @access private
*/
function update_Fields($blocknode, $blockInstance, $moduleInstance) {
if(empty($blocknode->fields) || empty($blocknode->fields->field)) return;
foreach($blocknode->fields->field as $fieldnode) {
$fieldInstance = Vtiger_Field::getInstance($fieldnode->fieldname, $moduleInstance);
if(!$fieldInstance) {
$fieldInstance = $this->import_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode);
} else {
$this->update_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode, $fieldInstance);
}
$this->__AddModuleFieldToCache($moduleInstance, $fieldInstance->name, $fieldInstance);
}
}
/**
* Update Field of the module
* @access private
*/
function update_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode, $fieldInstance) {
// TODO Handle field property update
if(!empty($fieldnode->helpinfo)) $fieldInstance->setHelpInfo($fieldnode->helpinfo);
if(!empty($fieldnode->masseditable)) $fieldInstance->setMassEditable($fieldnode->masseditable);
}
/**
* Import Custom views of the module
* @access private
*/
function update_CustomViews($modulenode, $moduleInstance) {
if(empty($modulenode->customviews) || empty($modulenode->customviews->customview)) return;
foreach($modulenode->customviews->customview as $customviewnode) {
$filterInstance = Vtiger_Filter::getInstance($customviewnode->viewname, $moduleInstance);
if(!$filterInstance) {
$filterInstance = $this->import_CustomView($modulenode, $moduleInstance, $customviewnode);
} else {
$this->update_CustomView($modulenode, $moduleInstance, $customviewnode, $filterInstance);
}
}
}
/**
* Update Custom View of the module
* @access private
*/
function update_CustomView($modulenode, $moduleInstance, $customviewnode, $filterInstance) {
// TODO Handle filter property update
}
/**
* Update Sharing Access of the module
* @access private
*/
function update_SharingAccess($modulenode, $moduleInstance) {
if(empty($modulenode->sharingaccess)) return;
// TODO Handle sharing access property update
}
/**
* Update Events of the module
* @access private
*/
function update_Events($modulenode, $moduleInstance) {
if(empty($modulenode->events) || empty($modulenode->events->event)) return;
if(Vtiger_Event::hasSupport()) {
foreach($modulenode->events->event as $eventnode) {
$this->update_Event($modulenode, $moduleInstance, $eventnode);
}
}
}
/**
* Update Event of the module
* @access private
*/
function update_Event($modulenode, $moduleInstance, $eventnode) {
//Vtiger_Event::register($moduleInstance, $eventnode->eventname, $eventnode->classname, $eventnode->filename);
// TODO Handle event property update
}
/**
* Update actions of the module
* @access private
*/
function update_Actions($modulenode, $moduleInstance) {
if(empty($modulenode->actions) || empty($modulenode->actions->action)) return;
foreach($modulenode->actions->action as $actionnode) {
$this->update_Action($modulenode, $moduleInstance, $actionnode);
}
}
/**
* Update action of the module
* @access private
*/
function update_Action($modulenode, $moduleInstance, $actionnode) {
// TODO Handle action property update
}
/**
* Update related lists of the module
* @access private
*/
function update_RelatedLists($modulenode, $moduleInstance) {
if(empty($modulenode->relatedlists) || empty($modulenode->relatedlists->relatedlist)) return;
$moduleInstance->deleteRelatedLists();
foreach($modulenode->relatedlists->relatedlist as $relatedlistnode) {
$relModuleInstance = $this->update_Relatedlist($modulenode, $moduleInstance, $relatedlistnode);
}
}
/**
* Import related list of the module.
* @access private
*/
function update_Relatedlist($modulenode, $moduleInstance, $relatedlistnode) {
$relModuleInstance = Vtiger_Module::getInstance($relatedlistnode->relatedmodule);
$label = $relatedlistnode->label;
$actions = false;
if(!empty($relatedlistnode->actions) && !empty($relatedlistnode->actions->action)) {
$actions = Array();
foreach($relatedlistnode->actions->action as $actionnode) {
$actions[] = "$actionnode";
}
}
if($relModuleInstance) {
$moduleInstance->unsetRelatedList($relModuleInstance, "$label", "$relatedlistnode->function");
$moduleInstance->setRelatedList($relModuleInstance, "$label", $actions, "$relatedlistnode->function");
}
return $relModuleInstance;
}
function update_CustomLinks($modulenode, $moduleInstance) {
if(empty($modulenode->customlinks) || empty($modulenode->customlinks->customlink)) return;
$moduleInstance->deleteLinks();
$this->import_CustomLinks($modulenode, $moduleInstance);
}
function update_CronTasks($modulenode) {
if(empty($modulenode->crons) || empty($modulenode->crons->cron)) return;
$cronTasks = Vtiger_Cron::listAllInstancesByModule($modulenode->name);
foreach ($modulenode->crons->cron as $importCronTask) {
foreach($cronTasks as $cronTask) {
if($cronTask->getName() == $importCronTask->name && $importCronTask->handler == $cronTask->getHandlerFile()) {
Vtiger_Cron::deregister($importCronTask->name);
}
}
if(empty($importCronTask->status)){
$importCronTask->status=Vtiger_Cron::$STATUS_ENABLED;
}
if((empty($importCronTask->sequence))){
$importCronTask->sequence=Vtiger_Cron::nextSequence();
}
Vtiger_Cron::register("$importCronTask->name","$importCronTask->handler", "$importCronTask->frequency", "$modulenode->name","$importCronTask->status","$importCronTask->sequence","$cronTask->description");
}
}
}
?>