include 文件夹。

This commit is contained in:
YUCHENG HU 2013-01-30 21:51:28 -05:00
parent e18b890f8e
commit 0b5ff56be0
1695 changed files with 513572 additions and 0 deletions

View File

@ -0,0 +1,23 @@
<?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.
*
********************************************************************************/
$moduleFilepath = 'modules/'.$_REQUEST['module'].'/'.$_REQUEST['file'].'.php';
if(file_exists($moduleFilepath) == false) {
$moduleFilepath = 'modules/Vtiger/'.$_REQUEST['file'].'.php';
}
checkFileAccessForInclusion($moduleFilepath);
require_once $moduleFilepath;
?>

67
include/Ajax/TagCloud.php Normal file
View File

@ -0,0 +1,67 @@
<?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.
*
********************************************************************************/
$ajaxaction = $_REQUEST["ajxaction"];
global $current_user;
global $default_charset;
$crmid = vtlib_purify($_REQUEST["recordid"]);
$module = vtlib_purify($_REQUEST["module"]);
$userid = $current_user->id;
if($ajaxaction == "SAVETAG")
{
require_once('include/freetag/freetag.class.php');
$tagfields=function_exists(iconv) ? @iconv("UTF-8",$default_charset,$_REQUEST['tagfields']) : $_REQUEST['tagfields'];
$tagfields =str_replace(array("'",'"'),'',$tagfields);
if($tagfields != "")
{
$freetag = new freetag();
if (isset($_REQUEST["tagfields"]) && trim($_REQUEST["tagfields"]) != "")
{
$freetag->tag_object($userid,$crmid,$tagfields,$module);
$tagcloud = $freetag->get_tag_cloud_html($module,$userid,$crmid);
echo $tagcloud;
}
}
else
{
echo ":#:FAILURE";
}
}
elseif($ajaxaction == 'GETTAGCLOUD')
{
require_once('include/freetag/freetag.class.php');
$freetag = new freetag();
if(trim($module) != "")
{
$tagcloud = $freetag->get_tag_cloud_html($module,$userid,$crmid);
echo $tagcloud;
}else
{
$tagcloud = $freetag->get_tag_cloud_html("",$userid);
echo $tagcloud;
}
}elseif($ajaxaction == 'DELETETAG')
{
if(is_numeric($_REQUEST['tagid']))
{
$tagid = $_REQUEST['tagid'];
global $adb;
$query="delete from vtiger_freetagged_objects where tag_id=? and object_id=?";
$result=$adb->pquery($query, array($tagid, $crmid));
echo 'SUCCESS';
}else
{
die("An invalid tagid to delete.");
}
}
?>

523
include/ChartUtils.php Normal file
View File

@ -0,0 +1,523 @@
<?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('include/utils/utils.php');
require_once 'include/utils/CommonUtils.php';
Class ChartUtils {
// Function to generate Bar Chart
public static function getBarChart($xaxisData, $yaxisData, $title='', $width='', $height='', $charttype='vertical', $cachedFileName=false, $target=false, $color='') {
global $log, $lang_crm, $default_charset;
require_once('include/utils/utils.php');
require_once('include/utils/GraphUtils.php');
include_once ('Image/Graph.php');
include_once ('Image/Canvas.php');
$barwidth = '70';
if ($cachedFileName === false) {
$cache_file_name = 'cache/images/bar_chart_' . time() . '.png';
} else {
$cache_file_name = $cachedFileName;
}
if (empty($width))
$width = '400';
if (empty($height))
$height = '300';
if ($target === false)
$target = array();
if (empty($color))
$color = 'black';
$alts = array();
$temp = array();
for ($i = 0; $i < count($xaxisData); $i++) {
$name = html_entity_decode($xaxisData[$i], ENT_QUOTES, $default_charset);
$pos = substr_count($name, " ");
$alts[] = $name;
//If the daatx value of a string is greater, adding '\n' to it so that it'll cme inh 2nd line
if (strlen($name) >= 14)
$name = substr($name, 0, 44);
if ($pos >= 2) {
$val = explode(" ", $name);
$n = count($val) - 1;
$x = "";
for ($j = 0; $j < count($val); $j++) {
if ($j != $n) {
$x .=" " . $val[$j];
} else {
$x .= "@#" . $val[$j];
}
}
$name = $x;
}
$name = str_replace("@#", " ", $name);
$temp[] = html_entity_decode($name, ENT_QUOTES, $default_charset);
}
$xaxisData = $temp;
// Set the basic parameters of the graph
$canvas = & Image_Canvas::factory('png', array('width' => $width, 'height' => $height, 'usemap' => true));
$imagemap = $canvas->getImageMap();
$graph = & Image_Graph::factory('graph', $canvas);
$font = & $graph->addNew('font', calculate_font_name($lang_crm));
$font->setSize(8);
$font_color = "#000000";
$font->setColor($font_color);
$graph->setFont($font);
$titlestr = & Image_Graph::factory('title', array($title, 8));
$plotarea = & Image_Graph::factory('plotarea', array(
'axis',
'axis',
$charttype
));
$graph->add(Image_Graph::vertical($titlestr, $plotarea, 5));
// Now create a bar plot
$max = 0;
// To create unique lables we need to keep track of lable name and its count
$uniquex = array();
$xlabels = array();
$dataset = & Image_Graph::factory('dataset');
if ($charttype == 'horizontal') {
$fill = & Image_Graph::factory('gradient', array(IMAGE_GRAPH_GRAD_VERTICAL_MIRRORED, $color, 'white'));
} else {
$fill = & Image_Graph::factory('gradient', array(IMAGE_GRAPH_GRAD_HORIZONTAL_MIRRORED, $color, 'white'));
}
for ($i = 0; $i < count($yaxisData); $i++) {
$x = 1 + $i;
if ($yaxisData[$i] >= $max)
$max = $yaxisData[$i];
$dataset->addPoint(
$x,
$yaxisData[$i],
array(
'url' => $target[$i],
'alt' => $alts[$i] . '=' . $yaxisData[$i]
)
);
$xlabels[$x] = $xaxisData[$i];
// To have unique names even in case of duplicates let us add the id
$xaxisData_appearance = $uniquex[$xaxisData[$i]];
if ($xaxisData_appearance == null) {
$uniquex[$xaxisData[$i]] = 1;
} else {
$xlabels[$x] = $xaxisData[$i] . ' [' . $xaxisData_appearance . ']';
$uniquex[$xaxisData[$i]] = $xaxisData_appearance + 1;
}
}
$bplot = & $plotarea->addNew('bar', $dataset);
$bplot->setFillStyle($fill);
//You can change the width of the bars if you like
if (!empty($xaxisData))
$bplot->setBarWidth($barwidth / count($xaxisData), "%");
//$bplot->setPadding(array('top'=>10));
$bplot->setBackground(Image_Graph::factory('gradient', array(IMAGE_GRAPH_GRAD_HORIZONTAL, 'white', 'white')));
$xaxis = & $plotarea->getAxis(IMAGE_GRAPH_AXIS_X);
$yaxis = & $plotarea->getAxis(IMAGE_GRAPH_AXIS_Y);
$yaxis->setFontSize(8);
$xaxis->setFontSize(8);
if ($charttype == 'horizontal') { // Invert X-axis and put Y-axis at bottom
$xaxis->setInverted(false);
$yaxis->setAxisIntersection('max');
}
// set grid
$gridY = & $plotarea->addNew('line_grid', IMAGE_GRAPH_AXIS_Y);
$gridY->setLineColor('#FFFFFF@0.5');
$gridY2 = & $plotarea->addNew('bar_grid', null, IMAGE_GRAPH_AXIS_Y);
$gridY2->setFillColor('#FFFFFF@0.2');
// Add some grace to y-axis so the bars doesn't go all the way to the end of the plot area
$yaxis->forceMaximum(round(($max * 1.1) + 0.5));
$ticks = get_tickspacing(round(($max * 1.1) + 0.5));
// First make the labels look right
if ($charttype == 'horizontal')
$yaxis->setFontAngle('vertical');
$yaxis->setLabelInterval($ticks[0]);
$yaxis->setTickOptions(-5, 0);
$yaxis->setLabelInterval($ticks[1], 2);
$yaxis->setTickOptions(-2, 0, 2);
// Create the xaxis labels
$array_data = & Image_Graph::factory('Image_Graph_DataPreprocessor_Array',
array($xlabels)
);
// The fix the tick marks
$xaxis->setDataPreprocessor($array_data);
$xaxis->forceMinimum(0.5);
$xaxis->forceMaximum(0.5 + count($yaxisData));
if ($charttype == 'vertical')
$xaxis->setFontAngle('vertical');
$xaxis->setLabelInterval(1);
$xaxis->setTickOptions(0, 0);
$xaxis->setLabelInterval(2, 2);
// set markers
if ($width > 400 && $height > 400) {
$marker = & $graph->addNew('value_marker', IMAGE_GRAPH_VALUE_Y);
$marker->setFillColor('000000@0.0');
$marker->setBorderColor('000000@0.0');
$marker->setFontSize(8);
// shift markers 20 pix right
if ($charttype == 'horizontal') {
$marker_pointing = & $graph->addNew('Image_Graph_Marker_Pointing', array(10, 0, & $marker));
} else {
$marker_pointing = & $graph->addNew('Image_Graph_Marker_Pointing', array(0, -10, & $marker));
}
$marker_pointing->setLineColor('000000@0.0');
$bplot->setMarker($marker_pointing);
}
//Getting the graph in the form of html page
$img = $graph->done(
array(
'tohtml' => true,
'border' => 0,
'filename' => $cache_file_name,
'filepath' => '',
'urlpath' => ''
));
return $img;
}
// Function to generate Pie Chart
public static function getPieChart($xaxisData, $yaxisData, $title='', $width='', $height='', $charttype='vertical', $cachedFileName=false, $target=false, $color='') {
global $log, $lang_crm, $default_charset;
require_once('include/utils/utils.php');
require_once('include/utils/GraphUtils.php');
include_once ('Image/Graph.php');
include_once ('Image/Canvas.php');
if ($cachedFileName === false) {
$cache_file_name = 'cache/images/pie_chart_' . time() . '.png';
} else {
$cache_file_name = $cachedFileName;
}
if (empty($width))
$width = '500';
if (empty($height))
$height = '400';
if ($target === false)
$target = array();
$alts = array();
$temp = array();
for ($i = 0; $i < count($xaxisData); $i++) {
$name = html_entity_decode($xaxisData[$i], ENT_QUOTES, $default_charset);
$pos = substr_count($name, " ");
$alts[] = $name;
//If the datax value of a string is greater, adding '\n' to it so that it'll come in 2nd line
if (strlen($name) >= 14)
$name = substr($name, 0, 34);
if ($pos >= 2) {
$val = explode(" ", $name);
$n = count($val) - 1;
$x = "";
for ($j = 0; $j < count($val); $j++) {
if ($j != $n) {
$x .=" " . $val[$j];
} else {
$x .= "@#" . $val[$j];
}
}
$name = $x;
}
$name = str_replace("@#", "\n", $name);
$temp[] = $name;
}
$xaxisData = $temp;
$width = $width + ($width / 5);
$canvas = & Image_Canvas::factory('png', array('width' => $width, 'height' => $height, 'usemap' => true));
$imagemap = $canvas->getImageMap();
$graph = & Image_Graph::factory('graph', $canvas);
$font = & $graph->addNew('font', calculate_font_name($lang_crm));
$font->setSize(8);
$font->setColor($color);
$graph->setFont($font);
// create the plotarea layout
$title = & Image_Graph::factory('title', array($title, 10));
$plotarea = & Image_Graph::factory('plotarea', array(
'category',
'axis'
));
$graph->add(Image_Graph::vertical($title, $plotarea, 5));
// To create unique lables we need to keep track of lable name and its count
$uniquex = array();
// Generate colours
$colors = color_generator(count($yaxisData), '#33DDFF', '#3322FF');
$dataset = & Image_Graph::factory('dataset');
$fills = & Image_Graph::factory('Image_Graph_Fill_Array');
$sum = 0;
$pcvalues = array();
for ($i = 0; $i < count($yaxisData); $i++) {
$sum += $yaxisData[$i];
}
for ($i = 0; $i < count($yaxisData); $i++) {
// To have unique names even in case of duplicates let us add the id
$datalabel = $xaxisData[$i];
$xaxisData_appearance = $uniquex[$xaxisData[$i]];
if ($xaxisData_appearance == null) {
$uniquex[$xaxisData[$i]] = 1;
} else {
$datalabel = $xaxisData[$i] . ' [' . $xaxisData_appearance . ']';
$uniquex[$xaxisData[$i]] = $xaxisData_appearance + 1;
}
$dataset->addPoint(
$datalabel,
$yaxisData[$i],
array(
'url' => $target[$i],
'alt' => $alts[$i] . '=' . sprintf('%0.1f%%', 100 * $yaxisData[$i] / $sum)
)
);
$pcvalues[$yaxisData[$i]] = sprintf('%0.1f%%', 100 * $yaxisData[$i] / $sum);
$fills->addColor($colors[$i]);
}
if ($sum == 0)
return null;
// create the pie chart and associate the filling colours
$gbplot = & $plotarea->addNew('pie', $dataset);
$plotarea->setPadding(array('top' => 0, 'bottom' => 0, 'left' => 0, 'right' => ($width / 20)));
$plotarea->hideAxis();
$gbplot->setFillStyle($fills);
// format the data values
$marker_array = & Image_Graph::factory('Image_Graph_DataPreprocessor_Array', array($pcvalues));
// set markers
$marker = & $graph->addNew('value_marker', IMAGE_GRAPH_VALUE_Y);
$marker->setDataPreprocessor($marker_array);
$marker->setFillColor('#FFFFFF');
$marker->setBorderColor($color);
$marker->setFontColor($color);
$marker->setFontSize(8);
$pointingMarker = & $graph->addNew('Image_Graph_Marker_Pointing_Angular', array(20, &$marker));
$gbplot->setMarker($pointingMarker);
$legend_box = & $plotarea->addNew('legend');
$legend_box->setPadding(array('top' => 20, 'bottom' => 0, 'left' => 0, 'right' => 0));
$legend_box->setFillColor('#F5F5F5');
$legend_box->showShadow();
$img = $graph->done(array(
'tohtml' => true,
'border' => 0,
'filename' => $cache_file_name,
'filepath' => '',
'urlpath' => ''
));
return $img;
}
//Generates Chart Data in form of an array from the Query Result of reports
public static function generateChartDataFromReports($queryResult, $groupbyField, $fieldDetails='', $reportid='') {
require_once 'modules/Reports/CustomReportUtils.php';
require_once('include/Webservices/Utils.php');
require_once('include/Webservices/Query.php');
global $adb, $current_user, $theme, $default_charset;
$inventorymodules = array('Quotes', 'SalesOrder', 'PurchaseOrder', 'Invoice', 'Products', 'PriceBooks', 'Vendors', 'Services');
$rows = $adb->num_rows($queryResult);
$condition = "is";
$current_theme = $theme;
$groupByFields = array();
$yaxisArray = array();
$ChartDataArray = array();
$target_val = array();
$report = new ReportRun($reportid);
$restrictedModules = array();
if($report->secondarymodule!='') {
$reportModules = explode(":",$report->secondarymodule);
} else {
$reportModules = array();
}
array_push($reportModules,$report->primarymodule);
$restrictedModules = false;
foreach($reportModules as $mod) {
if(isPermitted($mod,'index') != "yes" || vtlib_isModuleActive($mod) == false) {
if(!is_array($restrictedModules)) $restrictedModules = array();
$restrictedModules[] = $mod;
}
}
if(is_array($restrictedModules) && count($restrictedModules) > 0) {
$ChartDataArray['error'] = "<h4>".getTranslatedString('LBL_NO_ACCESS', 'Reports').' - '.implode(',', $restrictedModules)."</h4>";
return $ChartDataArray;
}
if ($fieldDetails != '') {
list($tablename, $colname, $module_field, $fieldname, $single) = explode(":", $fieldDetails);
list($module, $field) = split("_", $module_field);
$dateField = false;
if ($single == 'D') {
$dateField = true;
$query = "SELECT * FROM vtiger_reportgroupbycolumn WHERE reportid=? ORDER BY sortid";
$result = $adb->pquery($query, array($reportid));
$criteria = $adb->query_result($result, 0, 'dategroupbycriteria');
}
}
preg_match('/&amp;/', $groupbyField, $matches);
if (!empty($matches)) {
$groupfield = str_replace('&amp;', '&', $groupbyField);
$groupbyField = $report->replaceSpecialChar($groupfield);
}
$handler = vtws_getModuleHandlerFromName($module, $current_user);
$meta = $handler->getMeta();
$meta->retrieveMeta();
$referenceFields = $meta->getReferenceFieldDetails();
if($rows > 0) {
$resultRow = $adb->query_result_rowdata($queryResult, 0);
if(!array_key_exists($groupbyField, $resultRow)) {
$ChartDataArray['error'] = "<h4>".getTranslatedString('LBL_NO_PERMISSION_FIELD', 'Dashboard')."</h4>";
return $ChartDataArray;
}
}
for ($i = 0; $i < $rows; $i++) {
$groupFieldValue = $adb->query_result($queryResult, $i, strtolower($groupbyField));
$decodedGroupFieldValue = html_entity_decode($groupFieldValue, ENT_QUOTES, $default_charset);
if (!empty($groupFieldValue)) {
if (in_array($module_field, $report->append_currency_symbol_to_value)) {
$valueComp = explode('::', $groupFieldValue);
$groupFieldValue = $valueComp[1];
}
if ($dateField) {
if (!empty($groupFieldValue))
$groupByFields[] = CustomReportUtils::getXAxisDateFieldValue($groupFieldValue, $criteria);
else
$groupByFields[] = "Null";
}
else if (in_array($fieldname, array_keys($referenceFields))) {
if (count($referenceFields[$fieldname]) > 1) {
$refenceModule = CustomReportUtils::getEntityTypeFromName($decodedGroupFieldValue, $referenceFields[$fieldname]);
}
else {
$refenceModule = $referenceFields[$fieldname][0];
}
$groupByFields[] = $groupFieldValue;
if ($fieldname == 'currency_id' && in_array($module, $inventorymodules)) {
$tablename = 'vtiger_currency_info';
} elseif ($refenceModule == 'DocumentFolders' && $fieldname == 'folderid') {
$tablename = 'vtiger_attachmentsfolder';
$colname = 'foldername';
} else {
require_once "modules/$refenceModule/$refenceModule.php";
$focus = new $refenceModule();
$tablename = $focus->table_name;
$colname = $focus->list_link_field;
$condition = "c";
}
} else {
$groupByFields[] = $groupFieldValue;
}
$yaxisArray[] = $adb->query_result($queryResult, $i, 'groupby_count');
if ($fieldDetails != '') {
if ($dateField) {
$advanceSearchCondition = CustomReportUtils::getAdvanceSearchCondition($fieldDetails, $criteria, $groupFieldValue);
if ($module == 'Calendar') {
$link_val = "index.php?module=" . $module . "&query=true&action=ListView&" . $advanceSearchCondition;
}else
$link_val = "index.php?module=" . $module . "&query=true&action=index&" . $advanceSearchCondition;
}
else {
$cvid = getCvIdOfAll($module);
$esc_search_str = urlencode($decodedGroupFieldValue);
if ($single == 'DT') {
$esc_search_str = urlencode($groupFieldValue);
if (strtolower($fieldname) == 'modifiedtime' || strtolower($fieldname) == 'createdtime') {
$tablename = 'vtiger_crmentity';
$colname = $fieldname;
}
}
if ($fieldname == 'assigned_user_id') {
$tablename = 'vtiger_crmentity';
$colname = 'smownerid';
}
if ($module == 'Calendar') {
$link_val = "index.php?module=" . $module . "&action=ListView&search_text=" . $esc_search_str . "&search_field=" . $fieldname . "&searchtype=BasicSearch&query=true&operator=e&viewname=" . $cvid;
} else {
$link_val = "index.php?module=" . $module . "&action=index&search_text=" . $esc_search_str . "&search_field=" . $fieldname . "&searchtype=BasicSearch&query=true&operator=e&viewname=" . $cvid;
}
}
$target_val[] = $link_val;
}
}
}
if(count($groupByFields) == 0) {
$ChartDataArray['error'] = "<div class='componentName'>".getTranslatedString('LBL_NO_DATA', 'Reports')."</div";
}
$ChartDataArray['xaxisData'] = $groupByFields;
$ChartDataArray['yaxisData'] = $yaxisArray;
$ChartDataArray['targetLink'] = $target_val;
$theme = $current_theme;
return $ChartDataArray;
}
public static function getReportBarChart($queryResult, $groupbyField, $fieldDetails, $reportid, $charttype='horizontal') {
global $theme;
$BarChartDetails = self::generateChartDataFromReports($queryResult, $groupbyField, $fieldDetails, $reportid);
$groupbyFields = $BarChartDetails['xaxisData'];
$yaxisArray = $BarChartDetails['yaxisData'];
$targerLinks = $BarChartDetails['targetLink'];
if ($theme == "softed") {
$font_color = "#212473";
} else {
$font_color = "#000000";
}
if(!empty($BarChartDetails['error'])) {
return $BarChartDetails['error'];
} else {
$barChart = ChartUtils::getBarChart($groupbyFields, $yaxisArray, '', '350', '300', $charttype, false, $targerLinks, $font_color);
return $barChart;
}
}
public static function getReportPieChart($queryResult, $groupbyField, $fieldDetails, $reportid) {
global $theme;
$PieChartDetails = self::generateChartDataFromReports($queryResult, $groupbyField, $fieldDetails, $reportid);
$groupbyFields = $PieChartDetails['xaxisData'];
$yaxisArray = $PieChartDetails['yaxisData'];
$targerLinks = $PieChartDetails['targetLink'];
$charttype = 'vertical';
if ($theme == "softed") {
$font_color = "#212473";
} else {
$font_color = "#000000";
}
if(!empty($PieChartDetails['error'])) {
return $PieChartDetails['error'];
} else {
$pieChart = ChartUtils::getPieChart($groupbyFields, $yaxisArray, '', '350', '300', $charttype, false, $targerLinks, $font_color);
return $pieChart;
}
}
}
?>

364
include/ComboStrings.php Normal file
View File

@ -0,0 +1,364 @@
<?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.
*
********************************************************************************/
global $combo_strings;
$combo_strings = Array(
'accounttype_dom' => Array(''=>''
, 'Analyst'=>'Analyst'
, 'Competitor'=>'Competitor'
, 'Customer'=>'Customer'
, 'Integrator'=>'Integrator'
, 'Investor'=>'Investor'
, 'Partner'=>'Partner'
, 'Press'=>'Press'
, 'Prospect'=>'Prospect'
, 'Reseller'=>'Reseller'
, 'Other'=>'Other'
),
'industry_dom' => Array(''=>''
, 'Apparel'=>'Apparel'
, 'Banking'=>'Banking'
, 'Biotechnology'=>'Biotechnology'
, 'Chemicals'=>'Chemicals'
, 'Communications'=>'Communications'
, 'Construction'=>'Construction'
, 'Consulting'=>'Consulting'
, 'Education'=>'Education'
, 'Electronics'=>'Electronics'
, 'Energy'=>'Energy'
, 'Engineering'=>'Engineering'
, 'Entertainment'=>'Entertainment'
, 'Environmental'=>'Environmental'
, 'Finance'=>'Finance'
, 'Food & Beverage'=>'Food & Beverage'
, 'Government'=>'Government'
, 'Healthcare'=>'Healthcare'
, 'Hospitality'=>'Hospitality'
, 'Insurance'=>'Insurance'
, 'Machinery'=>'Machinery'
, 'Manufacturing'=>'Manufacturing'
, 'Media'=>'Media'
, 'Not For Profit'=>'Not For Profit'
, 'Recreation'=>'Recreation'
, 'Retail'=>'Retail'
, 'Shipping'=>'Shipping'
, 'Technology'=>'Technology'
, 'Telecommunications'=>'Telecommunications'
, 'Transportation'=>'Transportation'
, 'Utilities'=>'Utilities'
, 'Other'=>'Other'
),
'leadsource_dom' => Array(''=>''
, 'Cold Call'=>'Cold Call'
, 'Existing Customer'=>'Existing Customer'
, 'Self Generated'=>'Self Generated'
, 'Employee'=>'Employee'
, 'Partner'=>'Partner'
, 'Public Relations'=>'Public Relations'
, 'Direct Mail'=>'Direct Mail'
, 'Conference'=>'Conference'
, 'Trade Show'=>'Trade Show'
, 'Web Site'=>'Web Site'
, 'Word of mouth'=>'Word of mouth'
, 'Other'=>'Other'
),
'leadstatus_dom' => Array(''=>''
, 'Attempted to Contact'=>'Attempted to Contact'
, 'Cold'=>'Cold'
, 'Contact in Future'=>'Contact in Future'
, 'Contacted'=>'Contacted'
, 'Hot'=>'Hot'
, 'Junk Lead'=>'Junk Lead'
, 'Lost Lead'=>'Lost Lead'
, 'Not Contacted'=>'Not Contacted'
, 'Pre Qualified'=>'Pre Qualified'
, 'Qualified'=>'Qualified'
, 'Warm'=>'Warm'
),
'rating_dom' => Array(''=>''
, 'Acquired'=>'Acquired'
, 'Active'=>'Active'
, 'Market Failed'=>'Market Failed'
, 'Project Cancelled'=>'Project Cancelled'
, 'Shutdown'=>'Shutdown'
),
'opportunity_type_dom' => Array(''=>''
, 'Existing Business'=>'Existing Business'
, 'New Business'=>'New Business'
),
'sales_stage_dom' => Array('Prospecting'=>'Prospecting'
, 'Qualification'=>'Qualification'
, 'Needs Analysis'=>'Needs Analysis'
, 'Value Proposition'=>'Value Proposition'
, 'Id. Decision Makers'=>'Id. Decision Makers'
, 'Perception Analysis'=>'Perception Analysis'
, 'Proposal/Price Quote'=>'Proposal/Price Quote'
, 'Negotiation/Review'=>'Negotiation/Review'
, 'Closed Won'=>'Closed Won'
, 'Closed Lost'=>'Closed Lost'
),
'salutationtype_dom' => Array(''=>''
, 'Mr.'=>'Mr.'
, 'Ms.'=>'Ms.'
, 'Mrs.'=>'Mrs.'
, 'Dr.'=>'Dr.'
, 'Prof.'=>'Prof.'
),
'eventstatus_dom' => Array('Planned'=>'Planned'
, 'Held'=>'Held'
, 'Not Held'=>'Not Held'
),
'taskstatus_dom' => Array('Not Started'=>'Not Started'
, 'In Progress'=>'In Progress'
, 'Completed'=>'Completed'
, 'Pending Input'=>'Pending Input'
, 'Deferred'=>'Deferred'
, 'Planned'=>'Planned'
),
'taskpriority_dom' => Array('High'=>'High'
,'Medium'=>'Medium'
,'Low'=>'Low'
),
'duration_minutes_dom' => Array('00'=>'00'
, '15'=>'15'
, '30'=>'30'
, '45'=>'45'
),
'productcategory_dom' => Array(''=>''
, 'Hardware'=>'Hardware'
, 'Software'=>'Software'
, 'CRM Applications'=>'CRM Applications'
),
'manufacturer_dom' => Array(''=>''
, 'AltvetPet Inc.'=>'AltvetPet Inc.'
, 'LexPon Inc.'=>'LexPon Inc.'
, 'MetBeat Corp'=>'MetBeat Corp'
),
'ticketcategories_dom' => Array('Big Problem'=>'Big Problem'
,'Small Problem'=>'Small Problem'
,'Other Problem'=>'Other Problem'
),
'ticketpriorities_dom' => Array('Low'=>'Low'
,'Normal'=>'Normal'
,'High'=>'High'
,'Urgent'=>'Urgent'
),
'ticketseverities_dom' => Array('Minor'=>'Minor'
,'Major'=>'Major'
,'Feature'=>'Feature'
,'Critical'=>'Critical'
),
'ticketstatus_dom' => Array('Open'=>'Open'
,'In Progress'=>'In Progress'
,'Wait For Response'=>'Wait For Response'
,'Closed'=>'Closed'
),
'activitytype_dom' => Array('Call'=>'Call'
, 'Meeting'=>'Meeting'
),
'faqcategories_dom' => Array('General'=>'General'
),
'faqstatus_dom' => Array('Draft'=>'Draft'
,'Reviewed'=>'Reviewed'
,'Published'=>'Published'
,'Obsolete'=>'Obsolete'
),
'currency_dom' => Array('Rupees'=>'Rupees',
'Dollar'=>'Dollar',
'Euro'=>'Euro'
),
'visibility_dom' => Array('Private'=>'Private',
'Public'=>'Public'
),
'usageunit_dom' => Array('Box'=>'Box',
'Carton'=>'Carton',
'Dozen'=>'Dozen',
'Each'=>'Each',
'Hours'=>'Hours',
'Impressions'=>'Impressions',
'Lb'=>'Lb',
'M'=>'M',
'Pack'=>'Pack',
'Pages'=>'Pages',
'Pieces'=>'Pieces',
'Quantity'=>'Quantity',
'Reams'=>'Reams',
'Sheet'=>'Sheet',
'Spiral Binder'=>'Spiral Binder',
'Sq Ft'=>'Sq Ft'
),
'glacct_dom' => Array('300-Sales-Software'=>'300-Sales-Software',
'301-Sales-Hardware'=>'301-Sales-Hardware',
'302-Rental-Income'=>'302-Rental-Income',
'303-Interest-Income'=>'303-Interest-Income',
'304-Sales-Software-Support'=>'304-Sales-Software-Support',
'305-Sales Other'=>'305-Sales Other',
'306-Internet Sales'=>'306-Internet Sales',
'307-Service-Hardware Labor'=>'307-Service-Hardware Labor',
'308-Sales-Books'=>'308-Sales-Books'
),
'quotestage_dom' => Array('Created'=>'Created',
'Delivered'=>'Delivered',
'Reviewed'=>'Reviewed',
'Accepted'=>'Accepted',
'Rejected'=>'Rejected'
),
'carrier_dom' => Array('FedEx'=>'FedEx',
'UPS'=>'UPS',
'USPS'=>'USPS',
'DHL'=>'DHL',
'BlueDart'=>'BlueDart'
),
'taxclass_dom' => Array('SalesTax'=>'SalesTax',
'Vat'=>'Vat'
),
'recurringtype_dom' => Array(''=>'',
'Daily'=>'Daily',
'Weekly'=>'Weekly',
'Monthly'=>'Monthly',
'Yearly'=>'Yearly'
),
'invoicestatus_dom' => Array('AutoCreated'=>'AutoCreated',
'Created'=>'Created',
'Approved'=>'Approved',
'Sent'=>'Sent',
'Credit Invoice'=>'Credit Invoice',
'Paid'=>'Paid'
),
'postatus_dom' => Array('Created'=>'Created',
'Approved'=>'Approved',
'Delivered'=>'Delivered',
'Cancelled'=>'Cancelled',
'Received Shipment'=>'Received Shipment'
),
'sostatus_dom' => Array('Created'=>'Created',
'Approved'=>'Approved',
'Delivered'=>'Delivered',
'Cancelled'=>'Cancelled'
),
'campaignstatus_dom' => Array(''=>'',
'Planning'=>'Planning',
'Active'=>'Active',
'Inactive'=>'Inactive',
'Completed'=>'Completed',
'Cancelled'=>'Cancelled', ),
'campaigntype_dom' => Array(''=>'',
'Conference'=>'Conference',
'Webinar'=>'Webinar',
'Trade Show'=>'Trade Show', 'Public Relations'=>'Public Relations', 'Partners'=>'Partners',
'Referral Program'=>'Referral Program',
'Advertisement'=>'Advertisement',
'Banner Ads'=>'Banner Ads',
'Direct Mail'=>'Direct Mail',
'Email'=>'Email',
'Telemarketing'=>'Telemarketing',
'Others'=>'Others'
),
'expectedresponse_dom' => Array(''=>'',
'Excellent'=>'Excellent',
'Good'=>'Good',
'Average'=>'Average',
'Poor'=>'Poor'
),
'status_dom' => Array('Active'=>'Active',
'Inactive'=>'Inactive'
),
'activity_view_dom' => Array('Today'=>'Today',
'This Week'=>'This Week',
'This Month'=>'This Month',
'This Year'=>'This Year'
),
'lead_view_dom' => Array('Today'=>'Today',
'Last 2 Days'=>'Last 2 Days',
'Last Week'=>'Last Week'
),
'date_format_dom' => Array('dd-mm-yyyy'=>'dd-mm-yyyy',
'mm-dd-yyyy'=>'mm-dd-yyyy',
'yyyy-mm-dd'=>'yyyy-mm-dd'
),
'reminder_interval_dom' => Array('None'=>'None',
'1 Minute'=>'1 Minute',
'5 Minutes'=>'5 Minutes',
'15 Minutes'=>'15 Minutes',
'30 Minutes'=>'30 Minutes',
'45 Minutes'=>'45 Minutes',
'1 Hour'=>'1 Hour',
'1 Day'=>'1 Day'
),
'recurring_frequency_dom' => Array('--None--'=>'--None--',
'Daily' => 'Daily',
'Weekly' => 'Weekly',
'Monthly' => 'Monthly',
'Quarterly' => 'Quarterly',
'Yearly' => 'Yearly'
),
'payment_duration_dom' => Array('Net 30 days'=>'Net 30 days',
'Net 45 days'=>'Net 45 days',
'Net 60 days'=>'Net 60 days'
),
'campaignrelstatus_dom' => Array('--None--'=>'--None--',
'Contacted - Successful' => 'Contacted - Successful',
'Contacted - Unsuccessful' => 'Contacted - Unsuccessful',
'Contacted - Never Contact Again' => 'Contacted - Never Contact Again'
),
'currency_grouping_pattern_dom' => Array('123,456,789' => '123,456,789',
'123456789' => '123456789',
'123456,789' => '123456,789',
'12,34,56,789' => '12,34,56,789'
),
'currency_decimal_separator_dom' => Array("." => ".",
"," => ",",
"'" => "'",
" " => " ",
"$" => "$"
),
'currency_grouping_separator_dom' => Array("." => ".",
"," => ",",
"'" => "'",
" " => " ",
"$" => "$"
),
'currency_symbol_placement_dom' => Array("$1.0" => "$1.0",
"1.0$" => "1.0$"
),
);
require_once('modules/Users/UserTimeZonesArray.php');
$usertimezonesClass = new UserTimeZones();
$arrayOfSupportedTimeZones = $usertimezonesClass->userTimeZones();
$combo_strings['time_zone_dom'] = array_combine($arrayOfSupportedTimeZones,$arrayOfSupportedTimeZones);
?>

68
include/ComboUtil.php Normal file
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.
*
********************************************************************************/
require_once('include/utils/CommonUtils.php');
require_once('include/database/PearDatabase.php');
/** Function to returns the combo field values in array format
* @param $combofieldNames -- combofieldNames:: Type string array
* @returns $comboFieldArray -- comboFieldArray:: Type string array
*/
function getComboArray($combofieldNames)
{
global $log,$mod_strings;
$log->debug("Entering getComboArray(".$combofieldNames.") method ...");
global $adb,$current_user;
$roleid=$current_user->roleid;
$comboFieldArray = Array();
foreach ($combofieldNames as $tableName => $arrayName)
{
$fldArrName= $arrayName;
$arrayName = Array();
$sql = "select $tableName from vtiger_$tableName";
$params = array();
if(!is_admin($current_user))
{
$subrole = getRoleSubordinates($roleid);
if(count($subrole)> 0)
{
$roleids = $subrole;
array_push($roleids, $roleid);
}
else
{
$roleids = $roleid;
}
$sql = "select distinct $tableName from vtiger_$tableName inner join vtiger_role2picklist on vtiger_role2picklist.picklistvalueid = vtiger_$tableName.picklist_valueid where roleid in(". generateQuestionMarks($roleids) .") order by sortid";
$params = array($roleids);
}
$result = $adb->pquery($sql, $params);
while($row = $adb->fetch_array($result))
{
$val = $row[$tableName];
$arrayName[$val] = getTranslatedString($val);
}
$comboFieldArray[$fldArrName] = $arrayName;
}
$log->debug("Exiting getComboArray method ...");
return $comboFieldArray;
}
function getUniquePicklistID()
{
global $adb;
/*$sql="select id from vtiger_picklistvalues_seq";
$picklistvalue_id = $adb->query_result($adb->pquery($sql, array()),0,'id');
$qry = "update vtiger_picklistvalues_seq set id =?";
$adb->pquery($qry, array(++$picklistvalue_id));*/
return $adb->getUniqueID('vtiger_picklistvalues');
}
?>

285
include/CustomFieldUtil.php Normal file
View File

@ -0,0 +1,285 @@
<?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('include/database/PearDatabase.php');
require_once('include/utils/utils.php');
/**
* Function to get vtiger_field typename
* @param $uitype :: uitype -- Type integer
* returns the vtiger_field type name -- Type string
*/
function getCustomFieldTypeName($uitype)
{
global $mod_strings,$app_strings;
global $log;
$log->debug("Entering getCustomFieldTypeName(".$uitype.") method ...");
global $log;
$log->info("uitype is ".$uitype);
$fldname = '';
/*
* salutation type is an exception where the uitype 55 is considered to be as text.
*/
if($uitype == 1 || $uitype == 55 || $uitype == 255)
{
$fldname = $mod_strings['Text'];
}
elseif($uitype == 7)
{
$fldname = $mod_strings['Number'];
}
elseif($uitype == 9)
{
$fldname = $mod_strings['Percent'];
}
elseif($uitype == 5 || $uitype == 23)
{
$fldname = $mod_strings['Date'];
}
elseif($uitype == 13)
{
$fldname = $mod_strings['Email'];
}
elseif($uitype == 11)
{
$fldname = $mod_strings['Phone'];
}
elseif($uitype == 15 )
{
$fldname = $mod_strings['PickList'];
}
elseif($uitype == 17)
{
$fldname = $mod_strings['LBL_URL'];
}
elseif($uitype == 56)
{
$fldname = $mod_strings['LBL_CHECK_BOX'];
}
elseif($uitype == 71)
{
$fldname = $mod_strings['Currency'];
}
elseif($uitype == 21 || $uitype == 19)
{
$fldname = $mod_strings['LBL_TEXT_AREA'];
}
elseif($uitype == 33)
{
$fldname = $mod_strings['LBL_MULTISELECT_COMBO'];
}
elseif($uitype == 85)
{
$fldname = $mod_strings['Skype'];
}
$log->debug("Exiting getCustomFieldTypeName method ...");
return $fldname;
}
/**
* Function to get custom vtiger_fields
* @param $module :: vtiger_table name -- Type string
* returns customfields in key-value pair array format
*/
function getCustomFieldArray($module)
{
global $log;
$log->debug("Entering getCustomFieldArray(".$module.") method ...");
global $adb;
$custquery = "select tablename,fieldname from vtiger_field where tablename=? and vtiger_field.presence in (0,2) order by tablename";
$custresult = $adb->pquery($custquery, array('vtiger_'.strtolower($module).'cf'));
$custFldArray = Array();
$noofrows = $adb->num_rows($custresult);
for($i=0; $i<$noofrows; $i++)
{
$colName=$adb->query_result($custresult,$i,"fieldname");
$custFldArray[$colName] = $i;
}
$log->debug("Exiting getCustomFieldArray method ...");
return $custFldArray;
}
/**
* Function to get columnname and vtiger_fieldlabel from vtiger_field vtiger_table
* @param $module :: module name -- Type string
* @param $trans_array :: translated column vtiger_fields -- Type array
* returns trans_array in key-value pair array format
*/
function getCustomFieldTrans($module, $trans_array)
{
global $log;
$log->debug("Entering getCustomFieldTrans(".$module.",". $trans_array.") method ...");
global $adb;
$tab_id = getTabid($module);
$custquery = "select columnname,fieldlabel from vtiger_field where generatedtype=2 and vtiger_field.presence in (0,2) and tabid=?";
$custresult = $adb->pquery($custquery, array($tab_id));
$custFldArray = Array();
$noofrows = $adb->num_rows($custresult);
for($i=0; $i<$noofrows; $i++)
{
$colName=$adb->query_result($custresult,$i,"columnname");
$fldLbl = $adb->query_result($custresult,$i,"fieldlabel");
$trans_array[$colName] = $fldLbl;
}
$log->debug("Exiting getCustomFieldTrans method ...");
}
/**
* Function to get customfield record from vtiger_field vtiger_table
* @param $tab :: Tab ID -- Type integer
* @param $datatype :: vtiger_field name -- Type string
* @param $id :: vtiger_field Id -- Type integer
* returns the data result in string format
*/
function getCustomFieldData($tab,$id,$datatype)
{
global $log;
$log->debug("Entering getCustomFieldData(".$tab.",".$id.",".$datatype.") method ...");
global $adb;
$query = "select * from vtiger_field where tabid=? and fieldid=? and vtiger_field.presence in (0,2)";
$result = $adb->pquery($query, array($tab, $id));
$return_data=$adb->fetch_array($result);
$log->debug("Exiting getCustomFieldData method ...");
return $return_data[$datatype];
}
/**
* Function to get customfield type,length value,decimal value and picklist value
* @param $label :: vtiger_field typename -- Type string
* @param $typeofdata :: datatype -- Type string
* returns the vtiger_field type,length,decimal
* and picklist value in ';' separated array format
*/
function getFldTypeandLengthValue($label,$typeofdata)
{
global $log;
global $mod_strings,$app_strings;
$log->debug("Entering getFldTypeandLengthValue(".$label.",".$typeofdata.") method ...");
if($label == $mod_strings['Text'])
{
$types = explode("~",$typeofdata);
$data_array=array('0',$types[3]);
$fieldtype = implode(";",$data_array);
}
elseif($label == $mod_strings['Number'])
{
$types = explode("~",$typeofdata);
$data_decimal = explode(",",$types[2]);
$data_array=array('1',$data_decimal[0],$data_decimal[1]);
$fieldtype = implode(";",$data_array);
}
elseif($label == $mod_strings['Percent'])
{
$types = explode("~",$typeofdata);
$data_array=array('2','5',$types[3]);
$fieldtype = implode(";",$data_array);
}
elseif($label == $mod_strings['Currency'])
{
$types = explode("~",$typeofdata);
$data_decimal = explode(",",$types[2]);
$data_array=array('3',$data_decimal[0],$data_decimal[1]);
$fieldtype = implode(";",$data_array);
}
elseif($label == $mod_strings['Date'])
{
$fieldtype = '4';
}
elseif($label == $mod_strings['Email'])
{
$fieldtype = '5';
}
elseif($label == $mod_strings['Phone'])
{
$fieldtype = '6';
}
elseif($label == $mod_strings['PickList'])
{
$fieldtype = '7';
}
elseif($label == $mod_strings['LBL_URL'])
{
$fieldtype = '8';
}
elseif($label == $mod_strings['LBL_CHECK_BOX'])
{
$fieldtype = '9';
}
elseif($label == $mod_strings['LBL_TEXT_AREA'])
{
$fieldtype = '10';
}
elseif($label == $mod_strings['LBL_MULTISELECT_COMBO'])
{
$fieldtype = '11';
}
elseif($label == $mod_strings['Skype'])
{
$fieldtype = '12';
}
$log->debug("Exiting getFldTypeandLengthValue method ...");
return $fieldtype;
}
function getCalendarCustomFields($tabid,$mode='edit',$col_fields='') {
global $adb, $log, $current_user;
$log->debug("Entering getCalendarCustomFields($tabid, $mode, $col_fields)");
require('user_privileges/user_privileges_'.$current_user->id.'.php');
$block = getBlockId($tabid,"LBL_CUSTOM_INFORMATION");
$custparams = array($block, $tabid);
if($is_admin == true || $profileGlobalPermission[1] == 0 || $profileGlobalPermission[2] == 0) {
$custquery = "select * from vtiger_field where block=? AND vtiger_field.tabid=? ORDER BY fieldid";
} else {
$profileList = getCurrentUserProfileList();
$custquery = "SELECT vtiger_field.* FROM vtiger_field" .
" INNER JOIN vtiger_profile2field ON vtiger_profile2field.fieldid=vtiger_field.fieldid" .
" INNER JOIN vtiger_def_org_field ON vtiger_def_org_field.fieldid=vtiger_field.fieldid" .
" WHERE vtiger_field.block=? AND vtiger_field.tabid=? AND vtiger_profile2field.visible=0" .
" AND vtiger_def_org_field.visible=0 AND vtiger_profile2field.profileid IN (". generateQuestionMarks($profileList) .")";
if ($mode == 'edit') {
$custquery .= " AND vtiger_profile2field.readonly = 0";
}
$custquery .= " ORDER BY vtiger_field.fieldid";
array_push($custparams, $profileList);
}
$custresult = $adb->pquery($custquery, $custparams);
$custFldArray = Array();
$noofrows = $adb->num_rows($custresult);
for($i=0; $i<$noofrows; $i++)
{
$fieldname=$adb->query_result($custresult,$i,"fieldname");
$fieldlabel=$adb->query_result($custresult,$i,"fieldlabel");
$columnName=$adb->query_result($custresult,$i,"columnname");
$uitype=$adb->query_result($custresult,$i,"uitype");
$maxlength = $adb->query_result($custresult,$i,"maximumlength");
$generatedtype = $adb->query_result($custresult,$i,"generatedtype");
$typeofdata = $adb->query_result($custresult,$i,"typeofdata");
if ($mode == 'edit')
$custfld = getOutputHtml($uitype, $fieldname, $fieldlabel, $maxlength, $col_fields,$generatedtype,'Calendar',$mode, $typeofdata);
if ($mode == 'detail_view')
$custfld = getDetailViewOutputHtml($uitype, $fieldname, $fieldlabel, $col_fields,$generatedtype,$tabid);
$custFldArray[] = $custfld;
}
$log->debug("Exiting getCalendarCustomFields()");
return $custFldArray;
}
?>

87
include/DatabaseUtil.php Normal file
View File

@ -0,0 +1,87 @@
<?php
/*********************************************************************************
* The contents of this file are subject to the SugarCRM Public License Version 1.1.2
* ("License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is: SugarCRM Open Source
* The Initial Developer of the Original Code is SugarCRM, Inc.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.;
* All Rights Reserved.
* Contributor(s): ______________________________________.
********************************************************************************/
//Added to check database charset and $default_charset are set to UTF8.
//If both are not set to be UTF-8, Then we will show an alert message.
function check_db_utf8_support($conn) {
global $db_type;
if($db_type == 'pgsql')
return true;
$dbvarRS = &$conn->Execute("show variables like '%_database' ");
$db_character_set = null;
$db_collation_type = null;
while(!$dbvarRS->EOF) {
$arr = $dbvarRS->FetchRow();
$arr = array_change_key_case($arr);
switch($arr['variable_name']) {
case 'character_set_database' : $db_character_set = $arr['value']; break;
case 'collation_database' : $db_collation_type = $arr['value']; break;
}
// If we have all the required information break the loop.
if($db_character_set != null && $db_collation_type != null) break;
}
return (stristr($db_character_set, 'utf8') && stristr($db_collation_type, 'utf8'));
}
function get_db_charset($conn) {
global $db_type;
if($db_type == 'pgsql')
return 'UTF8';
$dbvarRS = &$conn->query("show variables like '%_database' ");
$db_character_set = null;
while(!$dbvarRS->EOF) {
$arr = $dbvarRS->FetchRow();
$arr = array_change_key_case($arr);
if($arr['variable_name'] == 'character_set_database') {
$db_character_set = $arr['value'];
break;
}
}
return $db_character_set;
}
//Make a count query
function mkCountQuery($query)
{
// Remove all the \n, \r and white spaces to keep the space between the words consistent.
// This is required for proper pattern matching for words like ' FROM ', 'ORDER BY', 'GROUP BY' as they depend on the spaces between the words.
$query = preg_replace("/[\n\r\s]+/"," ",$query);
//Strip of the current SELECT fields and replace them by "select count(*) as count"
// Space across FROM has to be retained here so that we do not have a clash with string "from" found in select clause
$query = "SELECT count(*) AS count ".substr($query, stripos($query,' FROM '),strlen($query));
//Strip of any "GROUP BY" clause
if(stripos($query,'GROUP BY') > 0)
$query = substr($query, 0, stripos($query,'GROUP BY'));
//Strip of any "ORDER BY" clause
if(stripos($query,'ORDER BY') > 0)
$query = substr($query, 0, stripos($query,'ORDER BY'));
//That's it
return( $query);
}
//Added for PHP version less than 5
if (!function_exists("stripos"))
{
function stripos($query,$needle)
{
return strpos(strtolower($query),strtolower($needle));
}
}
?>

View File

@ -0,0 +1,9 @@
<?php
/**
* File created by SAKTI PRASAD MISHRA on 31 oct, 2007.
* This file is included within "DetailView.tpl" to provide SESSION value to smarty template
*/
session_start();
$aAllBlockStatus = $_SESSION['BLOCKINITIALSTATUS'];
$this->assign("BLOCKINITIALSTATUS",$aAllBlockStatus);
?>

View File

@ -0,0 +1,114 @@
<?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.
*
********************************************************************************/
/*
* File containing methods to proceed with the ui validation for all the forms
*
*/
/**
* Get field validation information
*/
function getDBValidationData($tablearray, $tabid='') {
if($tabid != '') {
global $adb, $mod_strings;
$fieldModuleName = getTabModuleName($tabid);
$fieldres = $adb->pquery(
"SELECT fieldlabel,fieldname,typeofdata FROM vtiger_field
WHERE displaytype IN (1,3) AND presence in (0,2) AND tabid=?", Array($tabid));
$fieldinfos = Array();
while($fieldrow = $adb->fetch_array($fieldres)) {
$fieldlabel = getTranslatedString($fieldrow['fieldlabel'], $fieldModuleName);
$fieldname = $fieldrow['fieldname'];
$typeofdata= $fieldrow['typeofdata'];
$fieldinfos[$fieldname] = Array($fieldlabel => $typeofdata);
}
return $fieldinfos;
} else {
// TODO: Call the old API defined below in the file?
return getDBValidationData_510($tablearray, $tabid);
}
}
/** Function to get the details for fieldlabels for a given table array
* @param $tablearray -- tablearray:: Type string array (table names in array)
* @param $tabid -- tabid:: Type integer
* @returns $fieldName_array -- fieldName_array:: Type string array (field name details)
*
*/
function getDBValidationData_510($tablearray,$tabid='')
{
global $log;
$log->debug("Entering getDBValidationData(".$tablearray.",".$tabid.") method ...");
$sql = '';
$params = array();
$tab_con = "";
$numValues = count($tablearray);
global $adb,$mod_strings;
if($tabid!='') $tab_con = ' and tabid='. $adb->sql_escape_string($tabid);
for($i=0;$i<$numValues;$i++)
{
if(in_array("emails",$tablearray))
{
if($numValues > 1 && $i != $numValues-1)
{
$sql .= "select fieldlabel,fieldname,typeofdata from vtiger_field where tablename=? and tabid=10 and vtiger_field.presence in (0,2) and displaytype <> 2 union ";
array_push($params, $tablearray[$i]);
}
else
{
$sql .= "select fieldlabel,fieldname,typeofdata from vtiger_field where tablename=? and tabid=10 and vtiger_field.presence in (0,2) and displaytype <> 2 ";
array_push($params, $tablearray[$i]);
}
}
else
{
if($numValues > 1 && $i != $numValues-1)
{
$sql .= "select fieldlabel,fieldname,typeofdata from vtiger_field where tablename=? $tab_con and displaytype in (1,3) and vtiger_field.presence in (0,2) union ";
array_push($params, $tablearray[$i]);
}
else
{
$sql .= "select fieldlabel,fieldname,typeofdata from vtiger_field where tablename=? $tab_con and displaytype in (1,3) and vtiger_field.presence in (0,2)";
array_push($params, $tablearray[$i]);
}
}
}
$result = $adb->pquery($sql, $params);
$noofrows = $adb->num_rows($result);
$fieldModuleName = empty($tabid)? false : getTabModuleName($tabid);
$fieldName_array = Array();
for($i=0;$i<$noofrows;$i++)
{
// Translate label with reference to module language string
$fieldlabel = getTranslatedString($adb->query_result($result,$i,'fieldlabel'), $fieldModuleName);
$fieldname = $adb->query_result($result,$i,'fieldname');
$typeofdata = $adb->query_result($result,$i,'typeofdata');
//echo '<br> '.$fieldlabel.'....'.$fieldname.'....'.$typeofdata;
$fldLabel_array = Array();
$fldLabel_array[$fieldlabel] = $typeofdata;
$fieldName_array[$fieldname] = $fldLabel_array;
}
$log->debug("Exiting getDBValidationData method ...");
return $fieldName_array;
}
?>

View File

@ -0,0 +1,804 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Class for managing HTTP sessions
*
* Provides access to session-state values as well as session-level
* settings and lifetime management methods.
* Based on the standart PHP session handling mechanism
* it provides for you more advanced features such as
* database container, idle and expire timeouts, etc.
*
* PHP version 4
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTTP
* @package HTTP_Session
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Session.php,v 1.15 2007/07/14 12:11:54 troehr Exp $
* @link http://pear.php.net/package/HTTP_Session
* @since File available since Release 0.4.0
*/
// @const HTTP_SESSION_STARTED - The session was started with the current request
define("HTTP_SESSION_STARTED", 1);
// @const HTTP_SESSION_STARTED - No new session was started with the current request
define("HTTP_SESSION_CONTINUED", 2);
/**
* Class for managing HTTP sessions
*
* Provides access to session-state values as well as session-level
* settings and lifetime management methods.
* Based on the standart PHP session handling mechanism
* it provides for you more advanced features such as
* database container, idle and expire timeouts, etc.
*
* Example 1:
*
* <code>
* // Setting some options and detecting of a new session
* HTTP_Session::setCookieless(false);
* HTTP_Session::start('MySessionID');
* HTTP_Session::set('variable', 'Tet string');
* if (HTTP_Session::isNew()) {
* echo('new session was created with the current request');
* $visitors++; // Increase visitors count
* }
*
* //HTTP_Session::regenerateId();
* </code>
*
* Example 2:
*
* <code>
* // Using database container
* HTTP_Session::setContainer('DB');
* HTTP_Session::start();
* </code>
*
* Example 3:
*
* <code>
* // Setting timeouts
* HTTP_Session::start();
* HTTP_Session::setExpire(time() + 60 * 60); // expires in one hour
* HTTP_Session::setIdle(time()+ 10 * 60); // idles in ten minutes
* if (HTTP_Session::isExpired()) {
* // expired
* echo('Your session is expired!');
* HTTP_Session::destroy();
* }
* if (HTTP_Session::isIdle()) {
* // idle
* echo('You've been idle for too long!');
* HTTP_Session::destroy();
* }
* HTTP_Session::updateIdle();
* </code>
*
* @category HTTP
* @package HTTP_Session
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/HTTP_Session
* @since Class available since Release 0.4.0
*/
class HTTP_Session
{
/**
* Sets user-defined session storage functions
*
* Sets the user-defined session storage functions which are used
* for storing and retrieving data associated with a session.
* This is most useful when a storage method other than
* those supplied by PHP sessions is preferred.
* i.e. Storing the session data in a local database.
*
* @param string $container Container name
* @param array $container_options Container options
*
* @static
* @access public
* @return void
* @see session_set_save_handler()
*/
function setContainer($container, $container_options = null)
{
$container_class = 'HTTP_Session_Container_' . $container;
$container_classfile = 'HTTP/Session/Container/' . $container . '.php';
include_once $container_classfile;
$container = new $container_class($container_options);
$container->set();
}
/**
* Initializes session data
*
* Creates a session (or resumes the current one
* based on the session id being passed
* via a GET variable or a cookie).
* You can provide your own name and/or id for a session.
*
* @param string $name string Name of a session, default is 'SessionID'
* @param string $id string Id of a session which will be used
* only when the session is new
*
* @static
* @access public
* @return void
* @see session_name()
* @see session_id()
* @see session_start()
*/
function start($name = 'SessionID', $id = null)
{
HTTP_Session::name($name);
if ($id) {
HTTP_Session::id($id);
} elseif (is_null(HTTP_Session::detectID())) {
HTTP_Session::id($id ? $id : uniqid(dechex(rand())));
}
session_start();
if (!isset($_SESSION['__HTTP_Session_Info'])) {
$_SESSION['__HTTP_Session_Info'] = HTTP_SESSION_STARTED;
} else {
$_SESSION['__HTTP_Session_Info'] = HTTP_SESSION_CONTINUED;
}
}
/**
* Writes session data and ends session
*
* Session data is usually stored after your script
* terminated without the need to call HTTP_Session::stop(),
* but as session data is locked to prevent concurrent
* writes only one script may operate on a session at any time.
* When using framesets together with sessions you will
* experience the frames loading one by one due to this
* locking. You can reduce the time needed to load all the
* frames by ending the session as soon as all changes
* to session variables are done.
*
* @static
* @access public
* @return void
* @see session_write_close()
*/
function pause()
{
session_write_close();
}
/**
* Frees all session variables and destroys all data
* registered to a session
*
* This method resets the $_SESSION variable and
* destroys all of the data associated
* with the current session in its storage (file or DB).
* It forces new session to be started after this method
* is called. It does not unset the session cookie.
*
* @static
* @access public
* @return void
* @see session_unset()
* @see session_destroy()
*/
function destroy()
{
session_unset();
session_destroy();
// set session handlers again to avoid fatal error in case
// HTTP_Session::start() will be called afterwards
if (isset($GLOBALS['HTTP_Session_Container']) &&
is_a($GLOBALS['HTTP_Session_Container'], 'HTTP_Session_Container')) {
$GLOBALS['HTTP_Session_Container']->set();
}
}
/**
* Calls session_regenerate_id() if available
*
* @param bool $deleteOldSessionData Whether to delete data of old session
*
* @static
* @access public
* @return bool
*/
function regenerateId($deleteOldSessionData = false)
{
if (function_exists('session_regenerate_id')) {
return session_regenerate_id($deleteOldSessionData);
// emulate session_regenerate_id()
} else {
do {
$newId = uniqid(dechex(rand()));
} while ($newId === session_id());
if ($deleteOldSessionData) {
session_unset();
}
session_id($newId);
return true;
}
}
/**
* This function copies session data of specified id to specified table
*
* @param string $targetTable Table to replicate data to
* @param string $id ID of the session
*
* @static
* @access public
* @return bool
*/
function replicate($targetTable, $id = null)
{
return $GLOBALS['HTTP_Session_Container']->replicate($targetTable, $id);
}
/**
* Free all session variables
*
* @todo TODO Save expire and idle timestamps?
* @static
* @access public
* @return void
*/
function clear()
{
$info = $_SESSION['__HTTP_Session_Info'];
session_unset();
$_SESSION['__HTTP_Session_Info'] = $info;
}
/**
* Tries to find any session id in $_GET, $_POST or $_COOKIE
*
* @static
* @access private
* @return string Session ID (if exists) or null
*/
function detectID()
{
if (HTTP_Session::useCookies()) {
if (isset($_COOKIE[HTTP_Session::name()])) {
return $_COOKIE[HTTP_Session::name()];
}
} else {
if (isset($_GET[HTTP_Session::name()])) {
return $_GET[HTTP_Session::name()];
}
if (isset($_POST[HTTP_Session::name()])) {
return $_POST[HTTP_Session::name()];
}
}
return null;
}
/**
* Sets new name of a session
*
* @param string $name New name of a session
*
* @static
* @access public
* @return string Previous name of a session
* @see session_name()
*/
function name($name = null)
{
return isset($name) ? session_name($name) : session_name();
}
/**
* Sets new ID of a session
*
* @param string $id New ID of a session
*
* @static
* @access public
* @return string Previous ID of a session
* @see session_id()
*/
function id($id = null)
{
return isset($id) ? session_id($id) : session_id();
}
/**
* Sets the maximum expire time
*
* @param integer $time Time in seconds
* @param bool $add Add time to current expire time or not
*
* @static
* @access public
* @return void
*/
function setExpire($time, $add = false)
{
if ($add) {
if (!isset($_SESSION['__HTTP_Session_Expire_TS'])) {
$_SESSION['__HTTP_Session_Expire_TS'] = time() + $time;
}
// update session.gc_maxlifetime
$currentGcMaxLifetime = HTTP_Session::setGcMaxLifetime(null);
HTTP_Session::setGcMaxLifetime($currentGcMaxLifetime + $time);
} elseif (!isset($_SESSION['__HTTP_Session_Expire_TS'])) {
$_SESSION['__HTTP_Session_Expire_TS'] = $time;
}
}
/**
* Sets the maximum idle time
*
* Sets the time-out period allowed
* between requests before the session-state
* provider terminates the session.
*
* @param int $time Time in seconds
* @param bool $add Add time to current maximum idle time or not
*
* @static
* @access public
* @return void
*/
function setIdle($time, $add = false)
{
if ($add) {
$_SESSION['__HTTP_Session_Idle'] = $time;
} else {
// substract time again because it doesn't make any sense to provide
// the idle time as a timestamp
// keep $add functionality to provide BC
$_SESSION['__HTTP_Session_Idle'] = $time - time();
}
}
/**
* Returns the time up to the session is valid
*
* @static
* @access public
* @return integer Time when the session idles
*/
function sessionValidThru()
{
if (!isset($_SESSION['__HTTP_Session_Idle_TS']) ||
!isset($_SESSION['__HTTP_Session_Idle'])) {
return 0;
} else {
return $_SESSION['__HTTP_Session_Idle_TS'] +
$_SESSION['__HTTP_Session_Idle'];
}
}
/**
* Check if session is expired
*
* @static
* @access public
* @return bool
*/
function isExpired()
{
if (isset($_SESSION['__HTTP_Session_Expire_TS']) &&
$_SESSION['__HTTP_Session_Expire_TS'] < time()) {
return true;
} else {
return false;
}
}
/**
* Check if session is idle
*
* @static
* @access public
* @return bool
*/
function isIdle()
{
if (isset($_SESSION['__HTTP_Session_Idle_TS']) &&
(($_SESSION['__HTTP_Session_Idle_TS'] +
$_SESSION['__HTTP_Session_Idle']) < time())) {
return true;
} else {
return false;
}
}
/**
* Updates the idletime
*
* @static
* @access public
* @return void
*/
function updateIdle()
{
$_SESSION['__HTTP_Session_Idle_TS'] = time();
}
/**
* If optional parameter is specified it indicates
* whether the module will use cookies to store
* the session id on the client side
*
* It returns the previous value of this property
*
* @param bool $useCookies If specified it will replace the previous value
* of this property
*
* @static
* @access public
*
* @return bool The previous value of the property
*/
function useCookies($useCookies = null)
{
$return = ini_get('session.use_cookies') ? true : false;
if (isset($useCookies)) {
ini_set('session.use_cookies', $useCookies ? 1 : 0);
}
return $return;
}
/**
* Gets a value indicating whether the session
* was created with the current request
*
* You MUST call this method only after you have started
* the session with the HTTP_Session::start() method.
*
* @static
* @access public
* @return bool True if the session was created
* with the current request, false otherwise
*/
function isNew()
{
// The best way to check if a session is new is to check
// for existence of a session data storage
// with the current session id, but this is impossible
// with the default PHP module wich is 'files'.
// So we need to emulate it.
return !isset($_SESSION['__HTTP_Session_Info']) ||
$_SESSION['__HTTP_Session_Info'] == HTTP_SESSION_STARTED;
}
/**
* Register variable with the current session
*
* @param string $name Name of a global variable
*
* @deprecated Use set()/setRef() instead
*
* @static
* @access public
* @return bool
* @see session_register()
*/
function register($name)
{
return session_register($name);
}
/**
* Unregister a variable from the current session
*
* @param string $name Name of a global variable
*
* @deprecated Use get()/getRef() instead
*
* @static
* @access public
* @return bool
* @see session_unregister()
*/
function unregister($name)
{
return session_unregister($name);
}
/**
* Checks if a session variable is registered
*
* @param string $name Variable name
*
* @deprecated Use is_set() instead
*
* @static
* @access public
* @return bool
*/
function registered($name)
{
return session_is_registered($name);
}
/**
* Returns session variable
*
* @param string $name Name of a variable
* @param mixed $default Default value of a variable if not set
*
* @static
* @access public
* @return mixed Value of a variable
*/
function get($name, $default = null)
{
if (!isset($_SESSION[$name]) && isset($default)) {
$_SESSION[$name] = $default;
}
$return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null;
return $return;
}
/**
* Returns session variable by reference
*
* @param string $name Name of a variable
*
* @static
* @access public
* @return mixed Value of a variable
*/
function &getRef($name)
{
if (isset($_SESSION[$name])) {
$return =& $_SESSION[$name];
} else {
$return = null;
}
return $return;
}
/**
* Sets session variable
*
* @param string $name Name of a variable
* @param mixed $value Value of a variable
*
* @static
* @access public
* @return mixed Old value of a variable
*/
function set($name, $value)
{
$return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null;
if (null === $value) {
unset($_SESSION[$name]);
} else {
$_SESSION[$name] = $value;
}
return $return;
}
/**
* Sets session variable by reference
*
* @param string $name Name of a variable
* @param mixed $value Value of a variable
*
* @static
* @access public
* @return mixed Old value of a variable
*/
function setRef($name, &$value)
{
$return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null;
$_SESSION[$name] =& $value;
return $return;
}
/**
* Checks if a session variable is set
*
* @param string $name Variable name
*
* @static
* @access public
* @return bool
*/
function is_set($name)
{
return isset($_SESSION[$name]);
}
/**
* Returns local variable of a script
*
* Two scripts can have local variables with the same names
*
* @param string $name Name of a variable
* @param mixed $default Default value of a variable if not set
*
* @static
* @access public
* @return mixed Value of a local variable
*/
function &getLocal($name, $default = null)
{
$local = md5(HTTP_Session::localName());
if (!isset($_SESSION[$local]) || !is_array($_SESSION[$local])) {
$_SESSION[$local] = array();
}
if (!isset($_SESSION[$local][$name]) && isset($default)) {
$_SESSION[$local][$name] = $default;
}
return $_SESSION[$local][$name];
}
/**
* Sets local variable of a script.
* Two scripts can have local variables with the same names.
*
* @param string $name Name of a local variable
* @param mixed $value Value of a local variable
*
* @static
* @access public
* @return mixed Old value of a local variable
*/
function setLocal($name, $value)
{
$local = md5(HTTP_Session::localName());
if (!isset($_SESSION[$local]) || !is_array($_SESSION[$local])) {
$_SESSION[$local] = array();
}
$return = (isset($_SESSION[$local][$name])) ? $_SESSION[$local][$name]
: null;
if (null === $value) {
unset($_SESSION[$local][$name]);
} else {
$_SESSION[$local][$name] = $value;
}
return $return;
}
/**
* Sets new local name
*
* @param string $name New local name
*
* @static
* @access public
* @return string Previous local name
*/
function localName($name = null)
{
$return = (isset($GLOBALS['__HTTP_Session_Localname'])) ? $GLOBALS['__HTTP_Session_Localname']
: null;
if (!empty($name)) {
$GLOBALS['__HTTP_Session_Localname'] = $name;
}
return $return;
}
/**
* Initialize
*
* @static
* @access private
* @return void
*/
function _init()
{
// Disable auto-start of a sesion
ini_set('session.auto_start', 0);
// Set local name equal to the current script name
HTTP_Session::localName($_SERVER['PHP_SELF']);
}
/**
* If optional parameter is specified it indicates
* whether the session id will automatically be appended to
* all links
*
* It returns the previous value of this property
*
* @param bool $useTransSID If specified it will replace the previous value
* of this property
*
* @static
* @access public
* @return bool The previous value of the property
*/
function useTransSID($useTransSID = null)
{
$return = ini_get('session.use_trans_sid') ? true : false;
if (isset($useTransSID)) {
ini_set('session.use_trans_sid', $useTransSID ? 1 : 0);
}
return $return;
}
/**
* If optional parameter is specified it determines the number of seconds
* after which session data will be seen as 'garbage' and cleaned up
*
* It returns the previous value of this property
*
* @param bool $gcMaxLifetime If specified it will replace the previous value
* of this property
*
* @static
* @access public
* @return bool The previous value of the property
*/
function setGcMaxLifetime($gcMaxLifetime = null)
{
$return = ini_get('session.gc_maxlifetime');
if (isset($gcMaxLifetime) && is_int($gcMaxLifetime) && $gcMaxLifetime >= 1) {
ini_set('session.gc_maxlifetime', $gcMaxLifetime);
}
return $return;
}
/**
* If optional parameter is specified it determines the
* probability that the gc (garbage collection) routine is started
* and session data is cleaned up
*
* It returns the previous value of this property
*
* @param bool $gcProbability If specified it will replace the previous value
* of this property
*
* @static
* @access public
* @return bool The previous value of the property
*/
function setGcProbability($gcProbability = null)
{
$return = ini_get('session.gc_probability');
if (isset($gcProbability) &&
is_int($gcProbability) &&
$gcProbability >= 1 &&
$gcProbability <= 100) {
ini_set('session.gc_probability', $gcProbability);
}
return $return;
}
}
HTTP_Session::_init();
?>

View File

@ -0,0 +1,280 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Container class for storing session data
*
* PHP version 4
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTTP
* @package HTTP_Session
* @author Alexander Radivanovich <info@wwwlab.net>
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Container.php,v 1.8 2007/07/14 12:11:54 troehr Exp $
* @link http://pear.php.net/package/HTTP_Session
* @since File available since Release 0.4.0
*/
/**
* Container class for storing session data
*
* @category HTTP
* @package HTTP_Session
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/HTTP_Session
* @since Class available since Release 0.4.0
*/
class HTTP_Session_Container
{
/**
* Additional options for the container object
*
* @var array
* @access private
*/
var $options = array();
/**
* Constrtuctor method
*
* @param array $options Additional options for the container object
*
* @access public
* @return object
*/
function HTTP_Session_Container($options = null)
{
$this->_setDefaults();
if (is_array($options)) {
$this->_parseOptions();
}
}
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
}
/**
* Parse options passed to the container class
*
* @param array $options Options
*
* @access private
* @return void
*/
function _parseOptions($options)
{
foreach ($options as $option => $value) {
if (in_array($option, array_keys($this->options))) {
$this->options[$option] = $value;
}
}
}
/**
* This function is called by the session handler to initialize things
*
* @param string $save_path Save path
* @param string $session_name Session name
*
* @access public
* @return bool
*/
function open($save_path, $session_name)
{
return true;
}
/**
* This function is called when the page is finished
* executing and the session handler needs to close things off
*
* Has to be overwritten by each container class
*
* @access public
* @return bool
*/
function close()
{
return true;
}
/**
* This function is called by the session handler
* to read the data associated with a given session ID.
* This function must retrieve and return the session data
* for the session identified by $id.
*
* Has to be overwritten by each container class
*
* @param string $id ID of the session
*
* @access public
* @return string
*/
function read($id)
{
return '';
}
/**
* This function is called when the session handler
* has session data to save, which usually happens
* at the end of your script
*
* Has to be overwritten by each container class
*
* @param string $id ID of the session
* @param mixed $data The data associated with a given session ID
*
* @access public
* @return bool
*/
function write($id, $data)
{
return true;
}
/**
* This function is called when a session is destroyed.
* It is responsible for deleting the session and cleaning things up.
*
* Has to be overwritten by each container class
*
* @param string $id ID of the session
*
* @access public
* @return bool
*/
function destroy($id)
{
return true;
}
/**
* This function copies session data of specified id to specified table
*
* Has to be overwritten by each container class
*
* @param string $targetTable Table to replicate data to
* @param string $id ID of the session
*
* @access public
* @return bool
*/
function replicate($targetTable, $id = null)
{
return true;
}
/**
* This function is responsible for garbage collection.
* In the case of session handling, it is responsible
* for deleting old, stale sessions that are hanging around.
* The session handler will call this every now and then.
*
* Has to be overwritten by each container class
*
* @param integer $maxlifetime Maximum lifetime
*
* @access public
* @return bool
*/
function gc($maxlifetime)
{
return true;
}
/**
* Set session save handler
*
* @access public
* @return void
*/
function set()
{
$GLOBALS['HTTP_Session_Container'] =& $this;
session_module_name('user');
session_set_save_handler('HTTP_Session_Open',
'HTTP_Session_Close',
'HTTP_Session_Read',
'HTTP_Session_Write',
'HTTP_Session_Destroy',
'HTTP_Session_GC');
}
/**
* Destructor for compatibility with PHP >= 5.0.5
*
* @access private
* @return void
*/
function __destruct()
{
$GLOBALS['HTTP_Session_Container'] =& $this;
session_write_close();
}
}
// Delegate function calls to the object's methods
/** @ignore */
function HTTP_Session_Open($save_path, $session_name)
{
return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->open($save_path, $session_name)
: false;
}
/** @ignore */
function HTTP_Session_Close()
{
return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->close()
: false;
}
/** @ignore */
function HTTP_Session_Read($id)
{
return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->read($id)
: false;
}
/** @ignore */
function HTTP_Session_Write($id, $data)
{
return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->write($id, $data)
: false;
}
/** @ignore */
function HTTP_Session_Destroy($id)
{
return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->destroy($id)
: false;
}
/** @ignore */
function HTTP_Session_GC($maxlifetime)
{
return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->gc($maxlifetime)
: false;
}
?>

View File

@ -0,0 +1,364 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Database container for session data
*
* PEAR::DB database container
*
* PHP version 4
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTTP
* @package HTTP_Session
* @author Alexander Radivanovich <info@wwwlab.net>
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: DB.php,v 1.7 2007/07/14 12:11:54 troehr Exp $
* @link http://pear.php.net/package/HTTP_Session
* @since File available since Release 0.4.0
*/
require_once 'HTTP/Session/Container.php';
require_once 'DB.php';
/**
* Database container for session data
*
* Create the following table to store session data
* <code>
* CREATE TABLE `sessiondata` (
* `id` CHAR(32) NOT NULL,
* `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
* `data` TEXT NOT NULL,
* PRIMARY KEY (`id`)
* );
* </code>
*
* @category HTTP
* @package HTTP_Session
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/HTTP_Session
* @since Class available since Release 0.4.0
*/
class HTTP_Session_Container_DB extends HTTP_Session_Container
{
/**
* DB connection object
*
* @var object DB
* @access private
*/
var $db = null;
/**
* Session data cache id
*
* @var mixed
* @access private
*/
var $crc = false;
/**
* Constrtuctor method
*
* $options is an array with the options.<br>
* The options are:
* <ul>
* <li>'dsn' - The DSN string</li>
* <li>'table' - Table with session data, default is 'sessiondata'</li>
* <li>'autooptimize' - Boolean, 'true' to optimize
* the table on garbage collection, default is 'false'.</li>
* </ul>
*
* @param array $options Options
*
* @access public
* @return object
*/
function HTTP_Session_Container_DB($options)
{
$this->_setDefaults();
if (is_array($options)) {
$this->_parseOptions($options);
} else {
$this->options['dsn'] = $options;
}
}
/**
* Connect to database by using the given DSN string
*
* @param string $dsn DSN string
*
* @access private
* @return mixed Object on error, otherwise bool
*/
function _connect($dsn)
{
if (is_string($dsn) || is_array($dsn)) {
$this->db = DB::connect($dsn);
} else if (is_object($dsn) && is_a($dsn, "db_common")) {
$this->db = $dsn;
} else if (is_object($dsn) && DB::isError($dsn)) {
return new DB_Error($dsn->code, PEAR_ERROR_DIE);
} else {
return new PEAR_Error("The given dsn was not valid in file " . __FILE__
. " at line " . __LINE__,
41,
PEAR_ERROR_RETURN,
null,
null
);
}
if (DB::isError($this->db)) {
return new DB_Error($this->db->code, PEAR_ERROR_DIE);
}
return true;
}
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
$this->options['dsn'] = null;
$this->options['table'] = 'sessiondata';
$this->options['autooptimize'] = false;
}
/**
* Establish connection to a database
*
* @param string $save_path Save path
* @param string $session_name Session name
*
* @return bool
*/
function open($save_path, $session_name)
{
if (DB::isError($this->_connect($this->options['dsn']))) {
return false;
} else {
return true;
}
}
/**
* Free resources
*
* @return void
*/
function close()
{
return true;
}
/**
* Read session data
*
* @param string $id Session id
*
* @return void
*/
function read($id)
{
$query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
$this->options['table'],
$this->db->quoteSmart(md5($id)),
time());
$result = $this->db->getOne($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
$this->crc = strlen($result) . crc32($result);
return $result;
}
/**
* Write session data
*
* @param string $id Session id
* @param mixed $data Data
*
* @return bool
*/
function write($id, $data)
{
if ((false !== $this->crc) &&
($this->crc === strlen($data) . crc32($data))) {
// $_SESSION hasn't been touched, no need to update the blob column
$query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
$this->options['table'],
time() + ini_get('session.gc_maxlifetime'),
$this->db->quoteSmart(md5($id)));
} else {
// Check if table row already exists
$query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
$this->options['table'],
$this->db->quoteSmart(md5($id)));
$result = $this->db->getOne($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
if (0 == intval($result)) {
// Insert new row into table
$query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
$this->options['table'],
$this->db->quoteSmart(md5($id)),
time() + ini_get('session.gc_maxlifetime'),
$this->db->quoteSmart($data));
} else {
// Update existing row
$query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
$this->options['table'],
time() + ini_get('session.gc_maxlifetime'),
$this->db->quoteSmart($data),
$this->db->quoteSmart(md5($id)));
}
}
$result = $this->db->query($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Destroy session data
*
* @param string $id Session id
*
* @return void
*/
function destroy($id)
{
$query = sprintf("DELETE FROM %s WHERE id = %s",
$this->options['table'],
$this->db->quoteSmart(md5($id)));
$result = $this->db->query($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Replicate session data to table specified in option 'replicateBeforeDestroy'
*
* @param string $targetTable Table to replicate to
* @param string $id Id of record to replicate
*
* @access private
* @return bool
*/
function replicate($targetTable, $id = null)
{
if (is_null($id)) {
$id = HTTP_Session::id();
}
// Check if table row already exists
$query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
$targetTable,
$this->db->quoteSmart(md5($id)));
$result = $this->db->getOne($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
// Insert new row into dest table
if (0 == intval($result)) {
$query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
$targetTable,
$this->options['table'],
$this->db->quoteSmart(md5($id)));
} else {
// Update existing row
$query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s",
$targetTable,
$this->options['table'],
$this->db->quoteSmart(md5($id)));
}
$result = $this->db->query($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Garbage collection
*
* @param int $maxlifetime Maximum lifetime
*
* @return bool
*/
function gc($maxlifetime)
{
$query = sprintf("DELETE FROM %s WHERE expiry < %d",
$this->options['table'],
time());
$result = $this->db->query($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
if ($this->options['autooptimize']) {
switch($this->db->phptype) {
case 'mysql':
$query = sprintf("OPTIMIZE TABLE %s", $this->options['table']);
break;
case 'pgsql':
$query = sprintf("VACUUM %s", $this->options['table']);
break;
default:
$query = null;
break;
}
if (isset($query)) {
$result = $this->db->query($query);
if (DB::isError($result)) {
new DB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
}
}
return true;
}
}
?>

View File

@ -0,0 +1,364 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Database container for session data
*
* PEAR::MDB database container
*
* PHP version 4
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTTP
* @package HTTP_Session
* @author Alexander Radivanovich <info@wwwlab.net>
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: MDB.php,v 1.5 2007/07/14 12:11:55 troehr Exp $
* @link http://pear.php.net/package/HTTP_Session
* @since File available since Release 0.5.0
*/
require_once 'HTTP/Session/Container.php';
require_once 'MDB.php';
/**
* Database container for session data
*
* Create the following table to store session data
* <code>
* CREATE TABLE `sessiondata` (
* `id` CHAR(32) NOT NULL,
* `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
* `data` TEXT NOT NULL,
* PRIMARY KEY (`id`)
* );
* </code>
*
* @category HTTP
* @package HTTP_Session
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/HTTP_Session
* @since Class available since Release 0.4.0
*/
class HTTP_Session_Container_MDB extends HTTP_Session_Container
{
/**
* MDB connection object
*
* @var object MDB
* @access private
*/
var $db = null;
/**
* Session data cache id
*
* @var mixed
* @access private
*/
var $crc = false;
/**
* Constructor method
*
* $options is an array with the options.<br>
* The options are:
* <ul>
* <li>'dsn' - The DSN string</li>
* <li>'table' - Table with session data, default is 'sessiondata'</li>
* <li>'autooptimize' - Boolean, 'true' to optimize
* the table on garbage collection, default is 'false'.</li>
* </ul>
*
* @param array $options Options
*
* @access public
* @return object
*/
function HTTP_Session_Container_MDB($options)
{
$this->_setDefaults();
if (is_array($options)) {
$this->_parseOptions($options);
} else {
$this->options['dsn'] = $options;
}
}
/**
* Connect to database by using the given DSN string
*
* @param string $dsn DSN string
*
* @access private
* @return mixed Object on error, otherwise bool
*/
function _connect($dsn)
{
if (is_string($dsn) || is_array($dsn)) {
$this->db = MDB::connect($dsn);
} else if (is_object($dsn) && is_a($dsn, 'mdb_common')) {
$this->db = $dsn;
} else if (is_object($dsn) && MDB::isError($dsn)) {
return new MDB_Error($dsn->code, PEAR_ERROR_DIE);
} else {
return new PEAR_Error("The given dsn was not valid in file " . __FILE__
. " at line " . __LINE__,
41,
PEAR_ERROR_RETURN,
null,
null
);
}
if (MDB::isError($this->db)) {
return new MDB_Error($this->db->code, PEAR_ERROR_DIE);
}
return true;
}
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
$this->options['dsn'] = null;
$this->options['table'] = 'sessiondata';
$this->options['autooptimize'] = false;
}
/**
* Establish connection to a database
*
* @param string $save_path Save path
* @param string $session_name Session name
*
* @return bool
*/
function open($save_path, $session_name)
{
if (MDB::isError($this->_connect($this->options['dsn']))) {
return false;
} else {
return true;
}
}
/**
* Free resources
*
* @return bool
*/
function close()
{
return true;
}
/**
* Read session data
*
* @param string $id Session id
*
* @return mixed
*/
function read($id)
{
$query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
$this->options['table'],
$this->db->getTextValue(md5($id)),
time());
$result = $this->db->getOne($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
$this->crc = strlen($result) . crc32($result);
return $result;
}
/**
* Write session data
*
* @param string $id Session id
* @param mixed $data Data
*
* @return bool
*/
function write($id, $data)
{
if ((false !== $this->crc) &&
($this->crc === strlen($data) . crc32($data))) {
// $_SESSION hasn't been touched, no need to update the blob column
$query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
$this->options['table'],
time() + ini_get('session.gc_maxlifetime'),
$this->db->getTextValue(md5($id)));
} else {
// Check if table row already exists
$query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
$this->options['table'],
$this->db->getTextValue(md5($id)));
$result = $this->db->getOne($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
if (0 == intval($result)) {
// Insert new row into table
$query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
$this->options['table'],
$this->db->getTextValue(md5($id)),
time() + ini_get('session.gc_maxlifetime'),
$this->db->getTextValue($data));
} else {
// Update existing row
$query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
$this->options['table'],
time() + ini_get('session.gc_maxlifetime'),
$this->db->getTextValue($data),
$this->db->getTextValue(md5($id)));
}
}
$result = $this->db->query($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Destroy session data
*
* @param string $id Session id
*
* @return bool
*/
function destroy($id)
{
$query = sprintf("DELETE FROM %s WHERE id = %s",
$this->options['table'],
$this->db->getTextValue(md5($id)));
$result = $this->db->query($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Replicate session data to table specified in option 'replicateBeforeDestroy'
*
* @param string $targetTable Table to replicate to
* @param string $id Id of record to replicate
*
* @access private
* @return bool
*/
function replicate($targetTable, $id = null)
{
if (is_null($id)) {
$id = HTTP_Session::id();
}
// Check if table row already exists
$query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
$targetTable,
$this->db->getTextValue(md5($id)));
$result = $this->db->getOne($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
// Insert new row into dest table
if (0 == intval($result)) {
$query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
$targetTable,
$this->options['table'],
$this->db->getTextValue(md5($id)));
} else {
// Update existing row
$query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s",
$targetTable,
$this->options['table'],
$this->db->getTextValue(md5($id)));
}
$result = $this->db->query($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Garbage collection
*
* @param int $maxlifetime Maximum lifetime
*
* @return bool
*/
function gc($maxlifetime)
{
$query = sprintf("DELETE FROM %s WHERE expiry < %d",
$this->options['table'],
time());
$result = $this->db->query($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
if ($this->options['autooptimize']) {
switch($this->db->phptype) {
case 'mysql':
$query = sprintf("OPTIMIZE TABLE %s", $this->options['table']);
break;
case 'pgsql':
$query = sprintf("VACUUM %s", $this->options['table']);
break;
default:
$query = null;
break;
}
if (isset($query)) {
$result = $this->db->query($query);
if (MDB::isError($result)) {
new MDB_Error($result->code, PEAR_ERROR_DIE);
return false;
}
}
}
return true;
}
}
?>

View File

@ -0,0 +1,364 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Database container for session data
*
* PEAR::MDB2 database container
*
* PHP version 4
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTTP
* @package HTTP_Session
* @author Alexander Radivanovich <info@wwwlab.net>
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: MDB2.php,v 1.5 2007/07/14 12:11:55 troehr Exp $
* @link http://pear.php.net/package/HTTP_Session
* @since File available since Release 0.5.0
*/
require_once 'HTTP/Session/Container.php';
require_once 'MDB2.php';
/**
* Database container for session data
*
* Create the following table to store session data
* <code>
* CREATE TABLE `sessiondata` (
* `id` CHAR(32) NOT NULL,
* `expiry` INT UNSIGNED NOT NULL DEFAULT 0,
* `data` TEXT NOT NULL,
* PRIMARY KEY (`id`)
* );
* </code>
*
* @category HTTP
* @package HTTP_Session
* @author David Costa <gurugeek@php.net>
* @author Michael Metz <pear.metz@speedpartner.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/HTTP_Session
* @since Class available since Release 0.5.0
*/
class HTTP_Session_Container_MDB2 extends HTTP_Session_Container
{
/**
* MDB2 connection object
*
* @var object MDB2
* @access private
*/
var $db = null;
/**
* Session data cache id
*
* @var mixed
* @access private
*/
var $crc = false;
/**
* Constructor method
*
* $options is an array with the options.<br>
* The options are:
* <ul>
* <li>'dsn' - The DSN string</li>
* <li>'table' - Table with session data, default is 'sessiondata'</li>
* <li>'autooptimize' - Boolean, 'true' to optimize
* the table on garbage collection, default is 'false'.</li>
* </ul>
*
* @param array $options Options
*
* @access public
* @return void
*/
function HTTP_Session_Container_MDB2($options)
{
$this->_setDefaults();
if (is_array($options)) {
$this->_parseOptions($options);
} else {
$this->options['dsn'] = $options;
}
}
/**
* Connect to database by using the given DSN string
*
* @param string $dsn DSN string
*
* @access private
* @return mixed Object on error, otherwise bool
*/
function _connect($dsn)
{
if (is_string($dsn) || is_array($dsn)) {
$this->db = MDB2::connect($dsn);
} else if (is_object($dsn) && is_a($dsn, 'MDB2_Driver_Common')) {
$this->db = $dsn;
} else if (is_object($dsn) && MDB2::isError($dsn)) {
return $dsn;
} else {
return new PEAR_Error("The given dsn was not valid in file " . __FILE__
. " at line " . __LINE__,
41,
PEAR_ERROR_RETURN,
null,
null
);
}
if (MDB2::isError($this->db)) {
return new MDB2_Error($this->db->code, PEAR_ERROR_DIE);
}
return true;
}
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
$this->options['dsn'] = null;
$this->options['table'] = 'sessiondata';
$this->options['autooptimize'] = false;
}
/**
* Establish connection to a database
*
* @param string $save_path Save path
* @param string $session_name Session name
*
* @return bool
*/
function open($save_path, $session_name)
{
if (MDB2::isError($this->_connect($this->options['dsn']))) {
return false;
} else {
return true;
}
}
/**
* Free resources
*
* @return bool
*/
function close()
{
return true;
}
/**
* Read session data
*
* @param string $id Session id
*
* @return mixed
*/
function read($id)
{
$query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d",
$this->options['table'],
$this->db->quote(md5($id), 'text'),
time());
$result = $this->db->queryOne($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
$this->crc = strlen($result) . crc32($result);
return $result;
}
/**
* Write session data
*
* @param string $id Session id
* @param mixed $data Data
*
* @return bool
*/
function write($id, $data)
{
if ((false !== $this->crc) &&
($this->crc === strlen($data) . crc32($data))) {
// $_SESSION hasn't been touched, no need to update the blob column
$query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s",
$this->options['table'],
time() + ini_get('session.gc_maxlifetime'),
$this->db->quote(md5($id), 'text'));
} else {
// Check if table row already exists
$query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
$this->options['table'],
$this->db->quote(md5($id), 'text'));
$result = $this->db->queryOne($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
if (0 == intval($result)) {
// Insert new row into table
$query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)",
$this->options['table'],
$this->db->quote(md5($id), 'text'),
time() + ini_get('session.gc_maxlifetime'),
$this->db->quote($data, 'text'));
} else {
// Update existing row
$query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s",
$this->options['table'],
time() + ini_get('session.gc_maxlifetime'),
$this->db->quote($data, 'text'),
$this->db->quote(md5($id), 'text'));
}
}
$result = $this->db->query($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Destroy session data
*
* @param string $id Session id
*
* @return bool
*/
function destroy($id)
{
$query = sprintf("DELETE FROM %s WHERE id = %s",
$this->options['table'],
$this->db->quote(md5($id), 'text'));
$result = $this->db->query($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Replicate session data to table specified in option 'replicateBeforeDestroy'
*
* @param string $targetTable Table to replicate to
* @param string $id Id of record to replicate
*
* @access private
* @return bool
*/
function replicate($targetTable, $id = null)
{
if (is_null($id)) {
$id = HTTP_Session::id();
}
// Check if table row already exists
$query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s",
$targetTable,
$this->db->quote(md5($id), 'text'));
$result = $this->db->queryOne($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
// Insert new row into dest table
if (0 == intval($result)) {
$query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s",
$targetTable,
$this->options['table'],
$this->db->quote(md5($id), 'text'));
} else {
// Update existing row
$query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s",
$targetTable,
$this->options['table'],
$this->db->quote(md5($id), 'text'));
}
$result = $this->db->query($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
return true;
}
/**
* Garbage collection
*
* @param int $maxlifetime Maximum lifetime
*
* @return bool
*/
function gc($maxlifetime)
{
$query = sprintf("DELETE FROM %s WHERE expiry < %d",
$this->options['table'],
time());
$result = $this->db->query($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
if ($this->options['autooptimize']) {
switch($this->db->phptype) {
case 'mysql':
$query = sprintf("OPTIMIZE TABLE %s", $this->options['table']);
break;
case 'pgsql':
$query = sprintf("VACUUM %s", $this->options['table']);
break;
default:
$query = null;
break;
}
if (isset($query)) {
$result = $this->db->query($query);
if (MDB2::isError($result)) {
$this->db->raiseError($result->code, PEAR_ERROR_DIE);
return false;
}
}
}
return true;
}
}
?>

View File

@ -0,0 +1,202 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Database container for session data
*
* Memcache database container
*
* PHP version 4
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category HTTP
* @package HTTP_Session
* @author Chad Wagner <chad.wagner@gmail.com>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Memcache.php,v 1.3 2007/07/14 12:11:55 troehr Exp $
* @link http://pear.php.net/package/HTTP_Session
* @since File available since Release 0.5.6
*/
require_once 'HTTP/Session/Container.php';
/**
* Database container for session data
*
* @category HTTP
* @package HTTP_Session
* @author Chad Wagner <chad.wagner@gmail.com>
* @author Torsten Roehr <torsten.roehr@gmx.de>
* @copyright 1997-2007 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://pear.php.net/package/HTTP_Session
* @since Class available since Release 0.5.6
*/
class HTTP_Session_Container_Memcache extends HTTP_Session_Container
{
/**
* Memcache connection object
*
* @var object Memcache
* @access private
*/
var $mc;
/**
* Constructor method
*
* $options is an array with the options.<br>
* The options are:
* <ul>
* <li>'memcache' - Memcache object
* <li>'prefix' - Key prefix, default is 'sessiondata:'</li>
* </ul>
*
* @param array $options Options
*
* @access public
* @return object
*/
function HTTP_Session_Container_Memcache($options)
{
$this->_setDefaults();
if (is_array($options)) {
$this->_parseOptions($options);
}
}
/**
* Connect to database by using the given DSN string
*
* @param string $mc Memcache object
*
* @access private
* @return mixed Object on error, otherwise bool
*/
function _connect($mc)
{
if (is_object($mc) && is_a($mc, 'Memcache')) {
$this->mc = $mc;
} else {
return new PEAR_Error('The given memcache object was not valid in file '
. __FILE__ . ' at line ' . __LINE__,
41,
PEAR_ERROR_RETURN,
null,
null
);
}
return true;
}
/**
* Set some default options
*
* @access private
* @return void
*/
function _setDefaults()
{
$this->options['prefix'] = 'sessiondata:';
$this->options['memcache'] = null;
}
/**
* Establish connection to a database
*
* @param string $save_path Save path
* @param string $session_name Session name
*
* @access public
* @return mixed Object on error, otherwise bool
*/
function open($save_path, $session_name)
{
return $this->_connect($this->options['memcache']);
}
/**
* Free resources
*
* @access public
* @return bool
*/
function close()
{
return true;
}
/**
* Read session data
*
* @param string $id Session id
*
* @access public
* @return mixed
*/
function read($id)
{
$result = $this->mc->get($this->options['prefix'] . $id);
return $result;
}
/**
* Write session data
*
* @param string $id Session id
* @param mixed $data Session data
*
* @access public
* @return bool
*/
function write($id, $data)
{
$this->mc->set($this->options['prefix'] . $id,
$data,
MEMCACHE_COMPRESSED,
time() + ini_get('session.gc_maxlifetime'));
return true;
}
/**
* Destroy session data
*
* @param string $id Session id
*
* @access public
* @return bool
*/
function destroy($id)
{
$this->mc->delete($this->options['prefix'] . $id);
return true;
}
/**
* Garbage collection
*
* @param int $maxlifetime Maximum lifetime
*
* @access public
* @return bool
*/
function gc($maxlifetime)
{
return true;
}
}
?>

View File

@ -0,0 +1,16 @@
<?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.
************************************************************************************/
function handleInventoryProductRel($entity){
require_once("include/utils/InventoryUtils.php");
updateInventoryProductRel($entity);
}
?>

View File

@ -0,0 +1,417 @@
<?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/PDF/models/Model.php';
include_once 'vtlib/Vtiger/PDF/inventory/HeaderViewer.php';
include_once 'vtlib/Vtiger/PDF/inventory/FooterViewer.php';
include_once 'vtlib/Vtiger/PDF/inventory/ContentViewer.php';
include_once 'vtlib/Vtiger/PDF/inventory/ContentViewer2.php';
include_once 'vtlib/Vtiger/PDF/viewers/PagerViewer.php';
include_once 'vtlib/Vtiger/PDF/PDFGenerator.php';
include_once 'data/CRMEntity.php';
class Vtiger_InventoryPDFController {
protected $module;
protected $focus = null;
function __construct($module) {
$this->moduleName = $module;
}
function loadRecord($id) {
global $current_user;
$this->focus = $focus = CRMEntity::getInstance($this->moduleName);
$focus->retrieve_entity_info($id,$this->moduleName);
$focus->apply_field_security();
$focus->id = $id;
$this->associated_products = getAssociatedProducts($this->moduleName,$focus);
}
function getPDFGenerator() {
return new Vtiger_PDF_Generator();
}
function getContentViewer() {
if($this->focusColumnValue('hdnTaxType') == "individual") {
$contentViewer = new Vtiger_PDF_InventoryContentViewer();
} else {
$contentViewer = new Vtiger_PDF_InventoryTaxGroupContentViewer();
}
$contentViewer->setContentModels($this->buildContentModels());
$contentViewer->setSummaryModel($this->buildSummaryModel());
$contentViewer->setLabelModel($this->buildContentLabelModel());
$contentViewer->setWatermarkModel($this->buildWatermarkModel());
return $contentViewer;
}
function getHeaderViewer() {
$headerViewer = new Vtiger_PDF_InventoryHeaderViewer();
$headerViewer->setModel($this->buildHeaderModel());
return $headerViewer;
}
function getFooterViewer() {
$footerViewer = new Vtiger_PDF_InventoryFooterViewer();
$footerViewer->setModel($this->buildFooterModel());
$footerViewer->setLabelModel($this->buildFooterLabelModel());
$footerViewer->setOnLastPage();
return $footerViewer;
}
function getPagerViewer() {
$pagerViewer = new Vtiger_PDF_PagerViewer();
$pagerViewer->setModel($this->buildPagermodel());
return $pagerViewer;
}
function Output($filename, $type) {
if(is_null($this->focus)) return;
$pdfgenerator = $this->getPDFGenerator();
$pdfgenerator->setPagerViewer($this->getPagerViewer());
$pdfgenerator->setHeaderViewer($this->getHeaderViewer());
$pdfgenerator->setFooterViewer($this->getFooterViewer());
$pdfgenerator->setContentViewer($this->getContentViewer());
$pdfgenerator->generate($filename, $type);
}
// Helper methods
function buildContentModels() {
$associated_products = $this->associated_products;
$contentModels = array();
$productLineItemIndex = 0;
$totaltaxes = 0;
foreach($associated_products as $productLineItem) {
++$productLineItemIndex;
$contentModel = new Vtiger_PDF_Model();
$discountPercentage = 0.00;
$total_tax_percent = 0.00;
$producttotal_taxes = 0.00;
$quantity = ''; $listPrice = ''; $discount = ''; $taxable_total = '';
$tax_amount = ''; $producttotal = '';
$quantity = $productLineItem["qty{$productLineItemIndex}"];
$listPrice = $productLineItem["listPrice{$productLineItemIndex}"];
$discount = $productLineItem["discountTotal{$productLineItemIndex}"];
$taxable_total = $quantity * $listPrice - $discount;
$taxable_total = number_format($taxable_total, 2,'.',''); //Convert to 2 decimals
$producttotal = $taxable_total;
if($this->focus->column_fields["hdnTaxType"] == "individual") {
for($tax_count=0;$tax_count<count($productLineItem['taxes']);$tax_count++) {
$tax_percent = $productLineItem['taxes'][$tax_count]['percentage'];
$total_tax_percent += $tax_percent;
$tax_amount = (($taxable_total*$tax_percent)/100);
$producttotal_taxes += $tax_amount;
}
}
$producttotal_taxes = number_format($producttotal_taxes, 2,'.',''); //Convert to 2 decimals
$producttotal = $taxable_total+$producttotal_taxes;
$producttotal = number_format($producttotal, 2,'.',''); //Convert to 2 decimals
$tax = $producttotal_taxes;
$totaltaxes += $tax;
$totaltaxes = number_format($totaltaxes, 2,'.',''); //Convert to 2 decimals
$discountPercentage = $productLineItem["discount_percent{$productLineItemIndex}"];
$productName = $productLineItem["productName{$productLineItemIndex}"];
//get the sub product
$subProducts = $productLineItem["subProductArray{$productLineItemIndex}"];
if($subProducts != ''){
foreach($subProducts as $subProduct) {
$productName .="\n"." - ".decode_html($subProduct);
}
}
$contentModel->set('Name', $productName);
$contentModel->set('Code', $productLineItem["hdnProductcode{$productLineItemIndex}"]);
$contentModel->set('Quantity', $quantity);
$contentModel->set('Price', $this->formatPrice($listPrice));
$contentModel->set('Discount', $this->formatPrice($discount)."\n ($discountPercentage%)");
$contentModel->set('Tax', $this->formatPrice($tax)."\n ($total_tax_percent%)");
$contentModel->set('Total', $this->formatPrice($producttotal));
$contentModel->set('Comment', $productLineItem["comment{$productLineItemIndex}"]);
$contentModels[] = $contentModel;
}
$this->totaltaxes = $totaltaxes; //will be used to add it to the net total
return $contentModels;
}
function buildContentLabelModel() {
$labelModel = new Vtiger_PDF_Model();
$labelModel->set('Code', getTranslatedString('Product Code',$this->moduleName));
$labelModel->set('Name', getTranslatedString('Product Name',$this->moduleName));
$labelModel->set('Quantity', getTranslatedString('Quantity',$this->moduleName));
$labelModel->set('Price', getTranslatedString('Price',$this->moduleName));
$labelModel->set('Discount', getTranslatedString('Discount',$this->moduleName));
$labelModel->set('Tax', getTranslatedString('Tax',$this->moduleName));
$labelModel->set('Total', getTranslatedString('Total',$this->moduleName));
$labelModel->set('Comment', getTranslatedString('Comment'),$this->moduleName);
return $labelModel;
}
function buildSummaryModel() {
$associated_products = $this->associated_products;
$final_details = $associated_products[1]['final_details'];
$summaryModel = new Vtiger_PDF_Model();
$netTotal = $discount = $handlingCharges = $handlingTaxes = 0;
$adjustment = $grandTotal = 0;
$productLineItemIndex = 0;
$sh_tax_percent = 0;
foreach($associated_products as $productLineItem) {
++$productLineItemIndex;
$netTotal += $productLineItem["netPrice{$productLineItemIndex}"];
}
$netTotal = number_format(($netTotal + $this->totaltaxes), 2,'.', '');
$summaryModel->set(getTranslatedString("Net Total", $this->moduleName), $this->formatPrice($netTotal));
$discount_amount = $final_details["discount_amount_final"];
$discount_percent = $final_details["discount_percentage_final"];
$discount = 0.0;
if(!empty($discount_amount)) {
$discount = $discount_amount;
} else if(!empty($discount_percent)) {
$discount = (($discount_percent*$final_details["hdnSubTotal"])/100);
}
$summaryModel->set(getTranslatedString("Discount", $this->moduleName), $this->formatPrice($discount));
$group_total_tax_percent = '0.00';
//To calculate the group tax amount
if($final_details['taxtype'] == 'group') {
$group_tax_details = $final_details['taxes'];
for($i=0;$i<count($group_tax_details);$i++) {
$group_total_tax_percent += $group_tax_details[$i]['percentage'];
}
$summaryModel->set(getTranslatedString("Tax:", $this->moduleName)."($group_total_tax_percent%)", $this->formatPrice($final_details['tax_totalamount']));
}
//Shipping & Handling taxes
$sh_tax_details = $final_details['sh_taxes'];
for($i=0;$i<count($sh_tax_details);$i++) {
$sh_tax_percent = $sh_tax_percent + $sh_tax_details[$i]['percentage'];
}
//obtain the Currency Symbol
$currencySymbol = $this->buildCurrencySymbol();
$summaryModel->set(getTranslatedString("Shipping & Handling Charges", $this->moduleName), $this->formatPrice($final_details['shipping_handling_charge']));
$summaryModel->set(getTranslatedString("Shipping & Handling Tax:", $this->moduleName)."($sh_tax_percent%)", $this->formatPrice($final_details['shtax_totalamount']));
$summaryModel->set(getTranslatedString("Adjustment", $this->moduleName), $this->formatPrice($final_details['adjustment']));
$summaryModel->set(getTranslatedString("Grand Total : (in $currencySymbol)", $this->moduleName), $this->formatPrice($final_details['grandTotal'])); // TODO add currency string
return $summaryModel;
}
function buildHeaderModel() {
$headerModel = new Vtiger_PDF_Model();
$headerModel->set('title', $this->buildHeaderModelTitle());
$modelColumns = array($this->buildHeaderModelColumnLeft(), $this->buildHeaderModelColumnCenter(), $this->buildHeaderModelColumnRight());
$headerModel->set('columns', $modelColumns);
return $headerModel;
}
function buildHeaderModelTitle() {
return $this->moduleName;
}
function buildHeaderModelColumnLeft() {
global $adb;
// Company information
$result = $adb->pquery("SELECT * FROM vtiger_organizationdetails", array());
$num_rows = $adb->num_rows($result);
if($num_rows) {
$resultrow = $adb->fetch_array($result);
$addressValues = array();
$addressValues[] = $resultrow['address'];
if(!empty($resultrow['city'])) $addressValues[]= "\n".$resultrow['city'];
if(!empty($resultrow['state'])) $addressValues[]= ",".$resultrow['state'];
if(!empty($resultrow['code'])) $addressValues[]= $resultrow['code'];
if(!empty($resultrow['country'])) $addressValues[]= "\n".$resultrow['country'];
if(!empty($resultrow['phone'])) $additionalCompanyInfo[]= "\n".getTranslatedString("Phone: ", $this->moduleName). $resultrow['phone'];
if(!empty($resultrow['fax'])) $additionalCompanyInfo[]= "\n".getTranslatedString("Fax: ", $this->moduleName). $resultrow['fax'];
if(!empty($resultrow['website'])) $additionalCompanyInfo[]= "\n".getTranslatedString("Website: ", $this->moduleName). $resultrow['website'];
$modelColumnLeft = array(
'logo' => "test/logo/".$resultrow['logoname'],
'summary' => decode_html($resultrow['organizationname']),
'content' => $this->joinValues($addressValues, ' '). $this->joinValues($additionalCompanyInfo, ' ')
);
}
return $modelColumnLeft;
}
function buildHeaderModelColumnCenter() {
$customerName = $this->resolveReferenceLabel($this->focusColumnValue('account_id'), 'Accounts');
$contactName = $this->resolveReferenceLabel($this->focusColumnValue('contact_id'), 'Contacts');
$customerNameLabel = getTranslatedString('Customer Name', $this->moduleName);
$contactNameLabel = getTranslatedString('Contact Name', $this->moduleName);
$modelColumnCenter = array(
$customerNameLabel => $customerName,
$contactNameLabel => $contactName,
);
return $modelColumnCenter;
}
function buildHeaderModelColumnRight() {
$issueDateLabel = getTranslatedString('Issued Date', $this->moduleName);
$validDateLabel = getTranslatedString('Valid Date', $this->moduleName);
$billingAddressLabel = getTranslatedString('Billing Address', $this->moduleName);
$shippingAddressLabel = getTranslatedString('Shipping Address', $this->moduleName);
$modelColumnRight = array(
'dates' => array(
$issueDateLabel => $this->formatDate(date("Y-m-d")),
$validDateLabel => $this->formatDate($this->focusColumnValue('validtill')),
),
$billingAddressLabel => $this->buildHeaderBillingAddress(),
$shippingAddressLabel => $this->buildHeaderShippingAddress()
);
return $modelColumnRight;
}
function buildFooterModel() {
$footerModel = new Vtiger_PDF_Model();
$footerModel->set(Vtiger_PDF_InventoryFooterViewer::$DESCRIPTION_DATA_KEY, from_html($this->focusColumnValue('description')));
$footerModel->set(Vtiger_PDF_InventoryFooterViewer::$TERMSANDCONDITION_DATA_KEY, from_html($this->focusColumnValue('terms_conditions')));
return $footerModel;
}
function buildFooterLabelModel() {
$labelModel = new Vtiger_PDF_Model();
$labelModel->set(Vtiger_PDF_InventoryFooterViewer::$DESCRIPTION_LABEL_KEY, getTranslatedString('Description',$this->moduleName));
$labelModel->set(Vtiger_PDF_InventoryFooterViewer::$TERMSANDCONDITION_LABEL_KEY, getTranslatedString('Terms & Conditions',$this->moduleName));
return $labelModel;
}
function buildPagerModel() {
$footerModel = new Vtiger_PDF_Model();
$footerModel->set('format', '-%s-');
return $footerModel;
}
function getWatermarkContent() {
return '';
}
function buildWatermarkModel() {
$watermarkModel = new Vtiger_PDF_Model();
$watermarkModel->set('content', $this->getWatermarkContent());
return $watermarkModel;
}
function buildHeaderBillingAddress() {
$billPoBox = $this->focusColumnValues(array('bill_pobox'));
$billStreet = $this->focusColumnValues(array('bill_street'));
$billCity = $this->focusColumnValues(array('bill_city'));
$billState = $this->focusColumnValues(array('bill_state'));
$billCountry = $this->focusColumnValues(array('bill_country'));
$billCode = $this->focusColumnValues(array('bill_code'));
$address = $this->joinValues(array($billPoBox, $billStreet), ' ');
$address .= "\n".$this->joinValues(array($billCity, $billState), ',')." ".$billCode;
$address .= "\n".$billCountry;
return $address;
}
function buildHeaderShippingAddress() {
$shipPoBox = $this->focusColumnValues(array('ship_pobox'));
$shipStreet = $this->focusColumnValues(array('ship_street'));
$shipCity = $this->focusColumnValues(array('ship_city'));
$shipState = $this->focusColumnValues(array('ship_state'));
$shipCountry = $this->focusColumnValues(array('ship_country'));
$shipCode = $this->focusColumnValues(array('ship_code'));
$address = $this->joinValues(array($shipPoBox, $shipStreet), ' ');
$address .= "\n".$this->joinValues(array($shipCity, $shipState), ',')." ".$shipCode;
$address .= "\n".$shipCountry;
return $address;
}
function buildCurrencySymbol() {
global $adb;
$currencyId = $this->focus->column_fields['currency_id'];
if(!empty($currencyId)) {
$result = $adb->pquery("SELECT currency_symbol FROM vtiger_currency_info WHERE id=?", array($currencyId));
return decode_html($adb->query_result($result,0,'currency_symbol'));
}
return false;
}
function focusColumnValues($names, $delimeter="\n") {
if(!is_array($names)) {
$names = array($names);
}
$values = array();
foreach($names as $name) {
$value = $this->focusColumnValue($name, false);
if($value !== false) {
$values[] = $value;
}
}
return $this->joinValues($values, $delimeter);
}
function focusColumnValue($key, $defvalue='') {
$focus = $this->focus;
if(isset($focus->column_fields[$key])) {
return $focus->column_fields[$key];
}
return $defvalue;
}
function resolveReferenceLabel($id, $module=false) {
if(empty($id)) {
return '';
}
if($module === false) {
$module = getSalesEntityType($id);
}
$label = getEntityName($module, array($id));
return decode_html($label[$id]);
}
function joinValues($values, $delimeter= "\n") {
$valueString = '';
foreach($values as $value) {
if(empty($value)) continue;
$valueString .= $value . $delimeter;
}
return rtrim($valueString, $delimeter);
}
function formatNumber($value) {
return number_format($value);
}
function formatPrice($value, $decimal=2) {
$currencyField = new CurrencyField($value);
return $currencyField->getDisplayValue(null, true);
}
function formatDate($value) {
return DateTimeField::convertToUserFormat($value);
}
}
?>

View File

@ -0,0 +1,288 @@
<?php
/*********************************************************************************
* The contents of this file are subject to the SugarCRM Public License Version 1.1.2
* ("License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is: SugarCRM Open Source
* The Initial Developer of the Original Code is SugarCRM, Inc.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.;
* All Rights Reserved.
* Contributor(s): ______________________________________.
********************************************************************************/
/*********************************************************************************
* $Header$
* Description: generic list view class.
********************************************************************************/
require_once('include/logging.php');
require_once('include/ListView/ListViewSession.php');
class ListView {
var $local_theme = null;
var $local_app_strings= null;
var $local_image_path = null;
var $local_current_module = null;
var $local_mod_strings = null;
var $records_per_page = 20;
var $xTemplate = null;
var $xTemplatePath = null;
var $seed_data = null;
var $query_where = null;
var $query_limit = -1;
var $query_orderby = null;
var $header_title = "";
var $header_text = "";
var $log = null;
var $initialized = false;
var $querey_where_has_changed = false;
var $display_header_and_footer = true;
/**initializes ListView
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function ListView(){
global $log;
$log->debug("Entering ListView() method ...");
if(!$this->initialized){
global $list_max_entries_per_page;
$this->records_per_page = $list_max_entries_per_page + 0;
$this->initialized = true;
global $theme, $app_strings, $image_path, $currentModule;
$this->local_theme = $theme;
$this->local_app_strings = &$app_strings;
$this->local_image_path = $image_path;
$this->local_current_module = $currentModule;
if(empty($this->local_image_path)){
$this->local_image_path = 'themes/'.$theme.'/images';
}
$this->log = LoggerManager::getLogger('listView_'.$this->local_current_module);
$log->debug("Exiting ListView method ...");
}
}
/**sets the header title */
function setHeaderTitle($value){
global $log;
$log->debug("Entering setHeaderTitle(".$value.") method ...");
$this->header_title = $value;
$log->debug("Exiting setHeaderTitle method ...");
}
/**sets the header text this is text thats appended to the header vtiger_table and is usually used for the creation of buttons
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setHeaderText($value){
global $log;
$log->debug("Entering setHeaderText(".$value.") method ...");
$this->header_text = $value;
$log->debug("Exiting setHeaderText method ...");
}
/**sets the parameters dealing with the db
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setQuery($where, $limit, $orderBy, $varName, $allowOrderByOveride= true){
global $log;
$log->debug("Entering setQuery(".$where.",". $limit.",". $orderBy.",". $varName.",". $allowOrderByOveride.") method ...");
$this->query_where = $where;
if($this->getSessionVariable("query", "where") != $where){
$this->querey_where_has_changed = true;
$this->setSessionVariable("query", "where", $where);
}
$this->query_limit = $limit;
if(!$allowOrderByOveride){
$this->query_orderby = $orderBy;
$log->debug("Exiting setQuery method ...");
return;
}
$sortBy = $this->getSessionVariable($varName, "ORDER_BY") ;
if(empty($sortBy)){
$this->setUserVariable($varName, "ORDER_BY", $orderBy);
$sortBy = $orderBy;
}else{
$this->setUserVariable($varName, "ORDER_BY", $sortBy);
}
if($sortBy == 'amount'){
$sortBy = 'amount*1';
}
$desc = false;
$desc = $this->getSessionVariable($varName, $sortBy."_desc");
if(empty($desc))
$desc = false;
if(isset($_REQUEST[$this->getSessionVariableName($varName, "ORDER_BY")]))
$last = $this->getSessionVariable($varName, "ORDER_BY_LAST");
if(!empty($last) && $last == $sortBy){
$desc = !$desc;
}else {
$this->setSessionVariable($varName, "ORDER_BY_LAST", $sortBy);
}
$this->setSessionVariable($varName, $sortBy."_desc", $desc);
if(!empty($sortBy)){
if(substr_count(strtolower($sortBy), ' desc') == 0 && substr_count(strtolower($sortBy), ' asc') == 0){
if($desc){
$this->query_orderby = $sortBy.' desc';
}else{
$this->query_orderby = $sortBy.' asc';
}
}
else{
$this->query_orderby = $sortBy;
}
}else {
$this->query_orderby = "";
}
$log->debug("Exiting setQuery method ...");
}
/**sets the theme used only use if it is different from the global
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setTheme($theme){
global $log;
$log->debug("Entering setTheme(".$theme.") method ...");
$this->local_theme = $theme;
if(isset($this->xTemplate))$this->xTemplate->assign("THEME", $this->local_theme );
$log->debug("Exiting setTheme method ...");
}
/**sets the AppStrings used only use if it is different from the global
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setAppStrings(&$app_strings){
global $log;
$log->debug("Entering setAppStrings(".$app_strings.") method ...");
unset($this->local_app_strings);
$this->local_app_strings = $app_strings;
if(isset($this->xTemplate))$this->xTemplate->assign("APP", $this->local_app_strings );
$log->debug("Exiting setAppStrings method ...");
}
/**sets the ModStrings used
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setModStrings(&$mod_strings){
global $log;
$log->debug("Entering setModStrings(".$mod_strings.") method ...");
unset($this->local_module_strings);
$this->local_mod_strings = $mod_strings;
if(isset($this->xTemplate))$this->xTemplate->assign("MOD", $this->local_mod_strings );
$log->debug("Exiting setModStrings method ...");
}
/**sets the ImagePath used
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setImagePath($image_path){
global $log;
$log->debug("Entering setImagePath(".$image_path.") method ...");
$this->local_image_path = $image_path;
if(empty($this->local_image_path)){
$this->local_image_path = 'themes/'.$this->local_theme.'/images';
}
if(isset($this->xTemplate))$this->xTemplate->assign("IMAGE_PATH", $this->local_image_path );
$log->debug("Exiting setImagePath method ...");
}
/**sets the currentModule only use if this is different from the global
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setCurrentModule($currentModule){
global $log;
$log->debug("Entering setCurrentModule(".$currentModule.") method ...");
unset($this->local_current_module);
$this->local_current_module = $currentModule;
$this->log = LoggerManager::getLogger('listView_'.$this->local_current_module);
if(isset($this->xTemplate))$this->xTemplate->assign("MODULE_NAME", $this->local_current_module );
$log->debug("Exiting setCurrentModule method ...");
}
/**INTERNAL FUNCTION sets a session variable
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function setSessionVariable($localVarName,$varName, $value){
global $log;
$log->debug("Entering setSessionVariable(".$localVarName.",".$varName.",". $value.") method ...");
$_SESSION[$this->local_current_module."_".$localVarName."_".$varName] = $value;
$log->debug("Exiting setSessionVariable method ...");
}
function setUserVariable($localVarName,$varName, $value){
global $log;
$log->debug("Entering setUserVariable(".$localVarName.",".$varName.",". $value.") method ...");
global $current_user;
$current_user->setPreference($this->local_current_module."_".$localVarName."_".$varName, $value);
$log->debug("Exiting setUserVariable method ...");
}
/**INTERNAL FUNCTION returns a session variable first checking the querey for it then checking the session
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
function getSessionVariable($localVarName,$varName){
global $log;
$log->debug("Entering getSessionVariable(".$localVarName.",".$varName.") method ...");
if(isset($_REQUEST[$this->getSessionVariableName($localVarName, $varName)])){
$this->setSessionVariable($localVarName,$varName,vtlib_purify($_REQUEST[$this->getSessionVariableName($localVarName, $varName)]));
}
if(isset($_SESSION[$this->getSessionVariableName($localVarName, $varName)])){
$log->debug("Exiting getSessionVariable method ...");
return $_SESSION[$this->getSessionVariableName($localVarName, $varName)];
}
$log->debug("Exiting getSessionVariable method ...");
return "";
}
/**
* @return void
* @param unknown $localVarName
* @param unknown $varName
* @desc INTERNAL FUNCTION returns the session/query variable name
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function getSessionVariableName($localVarName,$varName){
global $log;
$log->debug("Entering getSessionVariableName(".$localVarName.",".$varName.") method ...");
$log->debug("Exiting getSessionVariableName method ...");
return $this->local_current_module."_".$localVarName."_".$varName;
}
}
?>

View File

@ -0,0 +1,717 @@
<?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.
*
*********************************************************************************/
/**
* Description of ListViewController
*
* @author MAK
*/
class ListViewController {
/**
*
* @var QueryGenerator
*/
private $queryGenerator;
/**
*
* @var PearDatabase
*/
private $db;
private $nameList;
private $typeList;
private $ownerNameList;
private $user;
private $picklistValueMap;
private $picklistRoleMap;
private $headerSortingEnabled;
public function __construct($db, $user, $generator) {
$this->queryGenerator = $generator;
$this->db = $db;
$this->user = $user;
$this->nameList = array();
$this->typeList = array();
$this->ownerNameList = array();
$this->picklistValueMap = array();
$this->picklistRoleMap = array();
$this->headerSortingEnabled = true;
}
public function isHeaderSortingEnabled() {
return $this->headerSortingEnabled;
}
public function setHeaderSorting($enabled) {
$this->headerSortingEnabled = $enabled;
}
public function setupAccessiblePicklistValueList($name) {
$isRoleBased = vtws_isRoleBasedPicklist($name);
$this->picklistRoleMap[$name] = $isRoleBased;
if ($this->picklistRoleMap[$name]) {
$this->picklistValueMap[$name] = getAssignedPicklistValues($name,$this->user->roleid, $this->db);
}
}
public function fetchNameList($field, $result) {
$referenceFieldInfoList = $this->queryGenerator->getReferenceFieldInfoList();
$fieldName = $field->getFieldName();
$rowCount = $this->db->num_rows($result);
$idList = array();
for ($i = 0; $i < $rowCount; $i++) {
$id = $this->db->query_result($result, $i, $field->getColumnName());
if (!isset($this->nameList[$fieldName][$id])) {
$idList[$id] = $id;
}
}
$idList = array_keys($idList);
if(count($idList) == 0) {
return;
}
$moduleList = $referenceFieldInfoList[$fieldName];
foreach ($moduleList as $module) {
$meta = $this->queryGenerator->getMeta($module);
if ($meta->isModuleEntity()) {
if($module == 'Users') {
$nameList = getOwnerNameList($idList);
} else {
//TODO handle multiple module names overriding each other.
$nameList = getEntityName($module, $idList);
}
} else {
$nameList = vtws_getActorEntityName($module, $idList);
}
$entityTypeList = array_intersect(array_keys($nameList), $idList);
foreach ($entityTypeList as $id) {
$this->typeList[$id] = $module;
}
if(empty($this->nameList[$fieldName])) {
$this->nameList[$fieldName] = array();
}
foreach ($entityTypeList as $id) {
$this->typeList[$id] = $module;
$this->nameList[$fieldName][$id] = $nameList[$id];
}
}
}
/**This function generates the List view entries in a list view
* Param $focus - module object
* Param $result - resultset of a listview query
* Param $navigation_array - navigation values in an array
* Param $relatedlist - check for related list flag
* Param $returnset - list query parameters in url string
* Param $edit_action - Edit action value
* Param $del_action - delete action value
* Param $oCv - vtiger_customview object
* Returns an array type
*/
function getListViewEntries($focus, $module,$result,$navigationInfo,$skipActions=false) {
require('user_privileges/user_privileges_'.$this->user->id.'.php');
global $listview_max_textlength, $theme,$default_charset;
$fields = $this->queryGenerator->getFields();
$whereFields = $this->queryGenerator->getWhereFields();
$meta = $this->queryGenerator->getMeta($this->queryGenerator->getModule());
$moduleFields = $meta->getModuleFields();
$accessibleFieldList = array_keys($moduleFields);
$listViewFields = array_intersect($fields, $accessibleFieldList);
$referenceFieldList = $this->queryGenerator->getReferenceFieldList();
foreach ($referenceFieldList as $fieldName) {
if (in_array($fieldName, $listViewFields)) {
$field = $moduleFields[$fieldName];
$this->fetchNameList($field, $result);
}
}
$db = PearDatabase::getInstance();
$rowCount = $db->num_rows($result);
$ownerFieldList = $this->queryGenerator->getOwnerFieldList();
foreach ($ownerFieldList as $fieldName) {
if (in_array($fieldName, $listViewFields)) {
$field = $moduleFields[$fieldName];
$idList = array();
for ($i = 0; $i < $rowCount; $i++) {
$id = $this->db->query_result($result, $i, $field->getColumnName());
if (!isset($this->ownerNameList[$fieldName][$id])) {
$idList[] = $id;
}
}
if(count($idList) > 0) {
if(!is_array($this->ownerNameList[$fieldName])) {
$this->ownerNameList[$fieldName] = getOwnerNameList($idList);
} else {
//array_merge API loses key information so need to merge the arrays
// manually.
$newOwnerList = getOwnerNameList($idList);
foreach ($newOwnerList as $id => $name) {
$this->ownerNameList[$fieldName][$id] = $name;
}
}
}
}
}
foreach ($listViewFields as $fieldName) {
$field = $moduleFields[$fieldName];
if(!$is_admin && ($field->getFieldDataType() == 'picklist' ||
$field->getFieldDataType() == 'multipicklist')) {
$this->setupAccessiblePicklistValueList($fieldName);
}
}
$useAsterisk = get_use_asterisk($this->user->id);
$data = array();
for ($i = 0; $i < $rowCount; ++$i) {
//Getting the recordId
if($module != 'Users') {
$baseTable = $meta->getEntityBaseTable();
$moduleTableIndexList = $meta->getEntityTableIndexList();
$baseTableIndex = $moduleTableIndexList[$baseTable];
$recordId = $db->query_result($result,$i,$baseTableIndex);
$ownerId = $db->query_result($result,$i,"smownerid");
}else {
$recordId = $db->query_result($result,$i,"id");
}
$row = array();
foreach ($listViewFields as $fieldName) {
$field = $moduleFields[$fieldName];
$uitype = $field->getUIType();
$rawValue = $this->db->query_result($result, $i, $field->getColumnName());
if($module == 'Calendar') {
$activityType = $this->db->query_result($result, $i, 'activitytype');
}
if($uitype != 8){
$value = html_entity_decode($rawValue,ENT_QUOTES,$default_charset);
} else {
$value = $rawValue;
}
if($module == 'Documents' && $fieldName == 'filename') {
$downloadtype = $db->query_result($result,$i,'filelocationtype');
if($downloadtype == 'I') {
$ext =substr($value, strrpos($value, ".") + 1);
$ext = strtolower($ext);
if($value != ''){
if($ext == 'bin' || $ext == 'exe' || $ext == 'rpm') {
$fileicon = "<img src='" . vtiger_imageurl('fExeBin.gif', $theme).
"' hspace='3' align='absmiddle' border='0'>";
} elseif($ext == 'jpg' || $ext == 'gif' || $ext == 'bmp') {
$fileicon = "<img src='".vtiger_imageurl('fbImageFile.gif', $theme).
"' hspace='3' align='absmiddle' border='0'>";
} elseif($ext == 'txt' || $ext == 'doc' || $ext == 'xls') {
$fileicon = "<img src='".vtiger_imageurl('fbTextFile.gif', $theme).
"' hspace='3' align='absmiddle' border='0'>";
} elseif($ext == 'zip' || $ext == 'gz' || $ext == 'rar') {
$fileicon = "<img src='".vtiger_imageurl('fbZipFile.gif', $theme).
"' hspace='3' align='absmiddle' border='0'>";
} else {
$fileicon = "<img src='".vtiger_imageurl('fbUnknownFile.gif',$theme)
. "' hspace='3' align='absmiddle' border='0'>";
}
}
} elseif($downloadtype == 'E') {
if(trim($value) != '' ) {
$fileicon = "<img src='" . vtiger_imageurl('fbLink.gif', $theme) .
"' alt='".getTranslatedString('LBL_EXTERNAL_LNK',$module).
"' title='".getTranslatedString('LBL_EXTERNAL_LNK',$module).
"' hspace='3' align='absmiddle' border='0'>";
} else {
$value = '--';
$fileicon = '';
}
} else {
$value = ' --';
$fileicon = '';
}
$fileName = $db->query_result($result,$i,'filename');
$downloadType = $db->query_result($result,$i,'filelocationtype');
$status = $db->query_result($result,$i,'filestatus');
$fileIdQuery = "select attachmentsid from vtiger_seattachmentsrel where crmid=?";
$fileIdRes = $db->pquery($fileIdQuery,array($recordId));
$fileId = $db->query_result($fileIdRes,0,'attachmentsid');
if($fileName != '' && $status == 1) {
if($downloadType == 'I' ) {
$value = "<a href='index.php?module=uploads&action=downloadfile&".
"entityid=$recordId&fileid=$fileId' title='".
getTranslatedString("LBL_DOWNLOAD_FILE",$module).
"' onclick='javascript:dldCntIncrease($recordId);'>".textlength_check($value).
"</a>";
} elseif($downloadType == 'E') {
$value = "<a target='_blank' href='$fileName' onclick='javascript:".
"dldCntIncrease($recordId);' title='".
getTranslatedString("LBL_DOWNLOAD_FILE",$module)."'>".textlength_check($value).
"</a>";
} else {
$value = ' --';
}
}
$value = $fileicon.$value;
} elseif($module == 'Documents' && $fieldName == 'filesize') {
$downloadType = $db->query_result($result,$i,'filelocationtype');
if($downloadType == 'I') {
$filesize = $value;
if($filesize < 1024)
$value=$filesize.' B';
elseif($filesize > 1024 && $filesize < 1048576)
$value=round($filesize/1024,2).' KB';
else if($filesize > 1048576)
$value=round($filesize/(1024*1024),2).' MB';
} else {
$value = ' --';
}
} elseif( $module == 'Documents' && $fieldName == 'filestatus') {
if($value == 1)
$value=getTranslatedString('yes',$module);
elseif($value == 0)
$value=getTranslatedString('no',$module);
else
$value='--';
} elseif( $module == 'Documents' && $fieldName == 'filetype') {
$downloadType = $db->query_result($result,$i,'filelocationtype');
if($downloadType == 'E' || $downloadType != 'I') {
$value = '--';
}
} elseif ($field->getUIType() == '27') {
if ($value == 'I') {
$value = getTranslatedString('LBL_INTERNAL',$module);
}elseif ($value == 'E') {
$value = getTranslatedString('LBL_EXTERNAL',$module);
}else {
$value = ' --';
}
}elseif ($field->getFieldDataType() == 'picklist') {
if ($value != '' && !$is_admin && $this->picklistRoleMap[$fieldName] &&
!in_array($value, $this->picklistValueMap[$fieldName])) {
$value = "<font color='red'>".getTranslatedString('LBL_NOT_ACCESSIBLE',
$module)."</font>";
} else {
$value = getTranslatedString($value,$module);
$value = textlength_check($value);
}
}elseif($field->getFieldDataType() == 'date' ||
$field->getFieldDataType() == 'datetime') {
if($value != '' && $value != '0000-00-00') {
$date = new DateTimeField($value);
$value = $date->getDisplayDate();
if($field->getFieldDataType() == 'datetime') {
$value .= (' ' . $date->getDisplayTime());
}
} elseif ($value == '0000-00-00') {
$value = '';
}
} elseif($field->getFieldDataType() == 'currency') {
if($value != '') {
if($field->getUIType() == 72) {
if($fieldName == 'unit_price') {
$currencyId = getProductBaseCurrency($recordId,$module);
$cursym_convrate = getCurrencySymbolandCRate($currencyId);
$currencySymbol = $cursym_convrate['symbol'];
} else {
$currencyInfo = getInventoryCurrencyInfo($module, $recordId);
$currencySymbol = $currencyInfo['currency_symbol'];
}
$value = number_format($value, 2,'.','');
$currencyValue = CurrencyField::convertToUserFormat($value, null, true);
$value = CurrencyField::appendCurrencySymbol($currencyValue, $currencySymbol);
} else {
//changes made to remove vtiger_currency symbol infront of each
//vtiger_potential amount
if ($value != 0) {
$value = CurrencyField::convertToUserFormat($value);
}
}
}
} elseif($field->getFieldDataType() == 'url') {
$matchPattern = "^[\w]+:\/\/^";
preg_match($matchPattern, $rawValue, $matches);
if(!empty ($matches[0])){
$value = '<a href="'.$rawValue.'" target="_blank">'.textlength_check($value).'</a>';
}else{
$value = '<a href="http://'.$rawValue.'" target="_blank">'.textlength_check($value).'</a>';
}
} elseif ($field->getFieldDataType() == 'email') {
if($_SESSION['internal_mailer'] == 1) {
//check added for email link in user detailview
$fieldId = $field->getFieldId();
$value = "<a href=\"javascript:InternalMailer($recordId,$fieldId,".
"'$fieldName','$module','record_id');\">".textlength_check($value)."</a>";
}else {
$value = '<a href="mailto:'.$rawValue.'">'.textlength_check($value).'</a>';
}
} elseif($field->getFieldDataType() == 'boolean') {
if($value == 1) {
$value = getTranslatedString('yes',$module);
} elseif($value == 0) {
$value = getTranslatedString('no',$module);
} else {
$value = '--';
}
} elseif($field->getUIType() == 98) {
$value = '<a href="index.php?action=RoleDetailView&module=Settings&parenttab='.
'Settings&roleid='.$value.'">'.textlength_check(getRoleName($value)).'</a>';
} elseif($field->getFieldDataType() == 'multipicklist') {
$value = ($value != "") ? str_replace(' |##| ',', ',$value) : "";
if(!$is_admin && $value != '') {
$valueArray = ($rawValue != "") ? explode(' |##| ',$rawValue) : array();
$notaccess = '<font color="red">'.getTranslatedString('LBL_NOT_ACCESSIBLE',
$module)."</font>";
$tmp = '';
$tmpArray = array();
foreach($valueArray as $index => $val) {
if(!$listview_max_textlength ||
!(strlen(preg_replace("/(<\/?)(\w+)([^>]*>)/i","",$tmp)) >
$listview_max_textlength)) {
if (!$is_admin && $this->picklistRoleMap[$fieldName] &&
!in_array(trim($val), $this->picklistValueMap[$fieldName])) {
$tmpArray[] = $notaccess;
$tmp .= ', '.$notaccess;
} else {
$tmpArray[] = $val;
$tmp .= ', '.$val;
}
} else {
$tmpArray[] = '...';
$tmp .= '...';
}
}
$value = implode(', ', $tmpArray);
$value = textlength_check($value);
}
} elseif ($field->getFieldDataType() == 'skype') {
$value = ($value != "") ? "<a href='skype:$value?call'>".textlength_check($value)."</a>" : "";
} elseif ($field->getFieldDataType() == 'phone') {
if($useAsterisk == 'true') {
$value = "<a href='javascript:;' onclick='startCall(&quot;$value&quot;, ".
"&quot;$recordId&quot;)'>".textlength_check($value)."</a>";
} else {
$value = textlength_check($value);
}
} elseif($field->getFieldDataType() == 'reference') {
$referenceFieldInfoList = $this->queryGenerator->getReferenceFieldInfoList();
$moduleList = $referenceFieldInfoList[$fieldName];
if(count($moduleList) == 1) {
$parentModule = $moduleList[0];
} else {
$parentModule = $this->typeList[$value];
}
if(!empty($value) && !empty($this->nameList[$fieldName]) && !empty($parentModule)) {
$parentMeta = $this->queryGenerator->getMeta($parentModule);
$value = textlength_check($this->nameList[$fieldName][$value]);
if ($parentMeta->isModuleEntity() && $parentModule != "Users") {
$value = "<a href='index.php?module=$parentModule&action=DetailView&".
"record=$rawValue' title='".getTranslatedString($parentModule, $parentModule)."'>$value</a>";
}
} else {
$value = '--';
}
} elseif($field->getFieldDataType() == 'owner') {
$value = textlength_check($this->ownerNameList[$fieldName][$value]);
} elseif ($field->getUIType() == 25) {
//TODO clean request object reference.
$contactId=$_REQUEST['record'];
$emailId=$this->db->query_result($result,$i,"activityid");
$result1 = $this->db->pquery("SELECT access_count FROM vtiger_email_track WHERE ".
"crmid=? AND mailid=?", array($contactId,$emailId));
$value=$this->db->query_result($result1,0,"access_count");
if(!$value) {
$value = 0;
}
} elseif($field->getUIType() == 8){
if(!empty($value)){
$temp_val = html_entity_decode($value,ENT_QUOTES,$default_charset);
$json = new Zend_Json();
$value = vt_suppressHTMLTags(implode(',',$json->decode($temp_val)));
}
} elseif ( in_array($uitype,array(7,9,90)) ) {
$value = "<span align='right'>".textlength_check($value)."</div>";
} else {
$value = textlength_check($value);
}
$parenttab = getParentTab();
$nameFields = $this->queryGenerator->getModuleNameFields($module);
$nameFieldList = explode(',',$nameFields);
if(in_array($fieldName, $nameFieldList) && $module != 'Emails' ) {
$value = "<a href='index.php?module=$module&parenttab=$parenttab&action=DetailView&record=".
"$recordId' title='".getTranslatedString($module, $module)."'>$value</a>";
} elseif($fieldName == $focus->list_link_field && $module != 'Emails') {
$value = "<a href='index.php?module=$module&parenttab=$parenttab&action=DetailView&record=".
"$recordId' title='".getTranslatedString($module, $module)."'>$value</a>";
}
// vtlib customization: For listview javascript triggers
$value = "$value <span type='vtlib_metainfo' vtrecordid='{$recordId}' vtfieldname=".
"'{$fieldName}' vtmodule='$module' style='display:none;'></span>";
// END
$row[] = $value;
}
//Added for Actions ie., edit and delete links in listview
$actionLinkInfo = "";
if(isPermitted($module,"EditView","") == 'yes'){
$edit_link = $this->getListViewEditLink($module,$recordId);
if(isset($navigationInfo['start']) && $navigationInfo['start'] > 1 && $module != 'Emails') {
$actionLinkInfo .= "<a href=\"$edit_link&start=".
$navigationInfo['start']."\">".getTranslatedString("LNK_EDIT",
$module)."</a> ";
} else {
$actionLinkInfo .= "<a href=\"$edit_link\">".getTranslatedString("LNK_EDIT",
$module)."</a> ";
}
}
if(isPermitted($module,"Delete","") == 'yes'){
$del_link = $this->getListViewDeleteLink($module,$recordId);
if($actionLinkInfo != "" && $del_link != "")
$actionLinkInfo .= " | ";
if($del_link != "")
$actionLinkInfo .= "<a href='javascript:confirmdelete(\"".
addslashes(urlencode($del_link))."\")'>".getTranslatedString("LNK_DELETE",
$module)."</a>";
}
// Record Change Notification
if(method_exists($focus, 'isViewed') &&
PerformancePrefs::getBoolean('LISTVIEW_RECORD_CHANGE_INDICATOR', true)) {
if(!$focus->isViewed($recordId)) {
$actionLinkInfo .= " | <img src='" . vtiger_imageurl('important1.gif',
$theme) . "' border=0>";
}
}
// END
if($actionLinkInfo != "" && !$skipActions) {
$row[] = $actionLinkInfo;
}
$data[$recordId] = $row;
}
return $data;
}
public function getListViewEditLink($module,$recordId, $activityType='') {
if($module == 'Emails')
return 'javascript:;" onclick="OpenCompose(\''.$recordId.'\',\'edit\');';
if($module != 'Calendar') {
$return_action = "index";
} else {
$return_action = 'ListView';
}
//Added to fix 4600
$url = getBasic_Advance_SearchURL();
$parent = getParentTab();
//Appending view name while editing from ListView
$link = "index.php?module=$module&action=EditView&record=$recordId&return_module=$module".
"&return_action=$return_action&parenttab=$parent".$url."&return_viewname=".
$_SESSION['lvs'][$module]["viewname"];
if($module == 'Calendar') {
if($activityType == 'Task') {
$link .= '&activity_mode=Task';
} else {
$link .= '&activity_mode=Events';
}
}
return $link;
}
public function getListViewDeleteLink($module,$recordId) {
$parenttab = getParentTab();
$viewname = $_SESSION['lvs'][$module]['viewname'];
//Added to fix 4600
$url = getBasic_Advance_SearchURL();
if($module == "Calendar")
$return_action = "ListView";
else
$return_action = "index";
//This is added to avoid the del link in Product related list for the following modules
$link = "index.php?module=$module&action=Delete&record=$recordId".
"&return_module=$module&return_action=$return_action".
"&parenttab=$parenttab&return_viewname=".$viewname.$url;
// vtlib customization: override default delete link for custom modules
$requestModule = vtlib_purify($_REQUEST['module']);
$requestRecord = vtlib_purify($_REQUEST['record']);
$requestAction = vtlib_purify($_REQUEST['action']);
$requestFile = vtlib_purify($_REQUEST['file']);
$isCustomModule = vtlib_isCustomModule($requestModule);
if($isCustomModule && (!in_array($requestAction, Array('index','ListView')) &&
($requestAction == $requestModule.'Ajax' && !in_array($requestFile, Array('index','ListView'))))) {
$link = "index.php?module=$requestModule&action=updateRelations&parentid=$requestRecord";
$link .= "&destination_module=$module&idlist=$entity_id&mode=delete&parenttab=$parenttab";
}
// END
return $link;
}
public function getListViewHeader($focus, $module,$sort_qry='',$sorder='',$orderBy='',
$skipActions=false) {
global $log, $singlepane_view;
global $theme;
$arrow='';
$qry = getURLstring($focus);
$theme_path="themes/".$theme."/";
$image_path=$theme_path."images/";
$header = Array();
//Get the vtiger_tabid of the module
$tabid = getTabid($module);
$tabname = getParentTab();
global $current_user;
require('user_privileges/user_privileges_'.$current_user->id.'.php');
$fields = $this->queryGenerator->getFields();
$whereFields = $this->queryGenerator->getWhereFields();
$meta = $this->queryGenerator->getMeta($this->queryGenerator->getModule());
$moduleFields = $meta->getModuleFields();
$accessibleFieldList = array_keys($moduleFields);
$listViewFields = array_intersect($fields, $accessibleFieldList);
//Added on 14-12-2005 to avoid if and else check for every list
//vtiger_field for arrow image and change order
$change_sorder = array('ASC'=>'DESC','DESC'=>'ASC');
$arrow_gif = array('ASC'=>'arrow_down.gif','DESC'=>'arrow_up.gif');
foreach($listViewFields as $fieldName) {
$field = $moduleFields[$fieldName];
if(in_array($field->getColumnName(),$focus->sortby_fields)) {
if($orderBy == $field->getColumnName()) {
$temp_sorder = $change_sorder[$sorder];
$arrow = "&nbsp;<img src ='".vtiger_imageurl($arrow_gif[$sorder], $theme)."' border='0'>";
} else {
$temp_sorder = 'ASC';
}
$label = getTranslatedString($field->getFieldLabelKey(), $module);
//added to display vtiger_currency symbol in listview header
if($label =='Amount') {
$label .=' ('.getTranslatedString('LBL_IN', $module).' '.
$user_info['currency_symbol'].')';
}
if($field->getUIType() == '9') {
$label .=' (%)';
}
if($module == 'Users' && $fieldName == 'User Name') {
$name = "<a href='javascript:;' onClick='getListViewEntries_js(\"".$module.
"\",\"parenttab=".$tabname."&order_by=".$field->getColumnName()."&sorder=".
$temp_sorder.$sort_qry."\");' class='listFormHeaderLinks'>".
getTranslatedString('LBL_LIST_USER_NAME_ROLE',$module)."".$arrow."</a>";
} else {
if($this->isHeaderSortingEnabled()) {
$name = "<a href='javascript:;' onClick='getListViewEntries_js(\"".$module.
"\",\"parenttab=".$tabname."&foldername=Default&order_by=".$field->getColumnName()."&start=".
$_SESSION["lvs"][$module]["start"]."&sorder=".$temp_sorder."".
$sort_qry."\");' class='listFormHeaderLinks'>".$label."".$arrow."</a>";
} else {
$name = $label;
}
}
$arrow = '';
} else {
$name = getTranslatedString($field->getFieldLabelKey(), $module);
}
//added to display vtiger_currency symbol in related listview header
if($name =='Amount') {
$name .=' ('.getTranslatedString('LBL_IN').' '.$user_info['currency_symbol'].')';
}
$header[]=$name;
}
//Added for Action - edit and delete link header in listview
if(!$skipActions && (isPermitted($module,"EditView","") == 'yes' ||
isPermitted($module,"Delete","") == 'yes'))
$header[] = getTranslatedString("LBL_ACTION", $module);
return $header;
}
public function getBasicSearchFieldInfoList() {
$fields = $this->queryGenerator->getFields();
$whereFields = $this->queryGenerator->getWhereFields();
$meta = $this->queryGenerator->getMeta($this->queryGenerator->getModule());
$moduleFields = $meta->getModuleFields();
$accessibleFieldList = array_keys($moduleFields);
$listViewFields = array_intersect($fields, $accessibleFieldList);
$basicSearchFieldInfoList = array();
foreach ($listViewFields as $fieldName) {
$field = $moduleFields[$fieldName];
$basicSearchFieldInfoList[$fieldName] = getTranslatedString($field->getFieldLabelKey(),
$this->queryGenerator->getModule());
}
return $basicSearchFieldInfoList;
}
public function getAdvancedSearchOptionString() {
$module = $this->queryGenerator->getModule();
$meta = $this->queryGenerator->getMeta($module);
$moduleFields = $meta->getModuleFields();
$i =0;
foreach ($moduleFields as $fieldName=>$field) {
if($field->getFieldDataType() == 'reference') {
$typeOfData = 'V';
} else if($field->getFieldDataType() == 'boolean') {
$typeOfData = 'C';
} else {
$typeOfData = $field->getTypeOfData();
$typeOfData = explode("~",$typeOfData);
$typeOfData = $typeOfData[0];
}
$label = getTranslatedString($field->getFieldLabelKey(), $module);
if(empty($label)) {
$label = $field->getFieldLabelKey();
}
if($label == "Start Date & Time") {
$fieldlabel = "Start Date";
}
$selected = '';
if($i++ == 0) {
$selected = "selected";
}
// place option in array for sorting later
//$blockName = getTranslatedString(getBlockName($field->getBlockId()), $module);
$blockName = getTranslatedString($field->getBlockName(), $module);
$fieldLabelEscaped = str_replace(" ","_",$field->getFieldLabelKey());
$optionvalue = $field->getTableName().":".$field->getColumnName().":".$fieldName.":".$module."_".$fieldLabelEscaped.":".$typeOfData;
$OPTION_SET[$blockName][$label] = "<option value=\'$optionvalue\' $selected>$label</option>";
}
// sort array on block label
ksort($OPTION_SET, SORT_STRING);
foreach ($OPTION_SET as $key=>$value) {
$shtml .= "<optgroup label='$key' class='select' style='border:none'>";
// sort array on field labels
ksort($value, SORT_STRING);
$shtml .= implode('',$value);
}
return $shtml;
}
}
?>

View File

@ -0,0 +1,86 @@
<?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.
*********************************************************************************/
global $app_strings, $mod_strings, $current_language, $currentModule, $theme;
global $list_max_entries_per_page;
require_once('Smarty_setup.php');
require_once('include/ListView/ListView.php');
require_once('modules/CustomView/CustomView.php');
require_once('include/DatabaseUtil.php');
checkFileAccessForInclusion("modules/$currentModule/$currentModule.php");
require_once("modules/$currentModule/$currentModule.php");
if(!is_string($_SESSION[$currentModule.'_listquery']) || !empty($_REQUEST['globalSearch'])){
// Custom View
$customView = new CustomView($currentModule);
$viewid = $customView->getViewId($currentModule);
$customview_html = $customView->getCustomViewCombo($viewid);
$viewinfo = $customView->getCustomViewByCvid($viewid);
if($viewid != "0"&& $viewid != 0){
$listquery = getListQuery($currentModule);
$list_query= $customView->getModifiedCvListQuery($viewid, $listquery, $currentModule);
}else{
$list_query = getListQuery($currentModule);
}
// Enabling Module Search
$url_string = '';
if($_REQUEST['query'] == 'true') {
if(!empty($_REQUEST['tagSearchText'])){
$searchValue = vtlib_purify($_REQUEST['globalSearchText']);
$where = '(' . getTagWhere($searchValue, $current_user->id) . ')';
} else if(!empty($_REQUEST['globalSearch'])){
$searchValue = vtlib_purify($_REQUEST['globalSearchText']);
$where = '(' . getUnifiedWhere($list_query,$currentModule,$searchValue) . ')';
$url_string .= '&query=true&globalSearch=true&globalSearchText='.$searchValue;
}else{
list($where, $ustring) = split('#@@#', getWhereCondition($currentModule));
$url_string .= "&query=true$ustring";
}
}
//print_r($where);
if($where != '') {
$list_query = "$list_query AND $where";
$_SESSION['export_where'] = $where;
}else{
unset($_SESSION['export_where']);
}
// Sorting
if($order_by) {
if($order_by == 'smownerid'){
if( $adb->dbType == "pgsql"){
$list_query .= ' GROUP BY user_name';
}
$list_query .= ' ORDER BY user_name '.$sorder;
}else {
$tablename = getTableNameForField($currentModule, $order_by);
$tablename = ($tablename != '')? ($tablename . '.') : '';
if( $adb->dbType == "pgsql"){
$list_query .= ' GROUP BY '. $tablename . $order_by;
}
$list_query .= ' ORDER BY ' . $tablename . $order_by . ' ' . $sorder;
}
}
}else{
//TODO: remove after calendar module listview cleanup.
//its failing for calendar module.
$dummyQuery = getListQuery($currentModule);
$list_query = $_SESSION[$currentModule.'_listquery'];
}
$count_result = $adb->query(mkCountQuery($list_query));
$noofrows = $adb->query_result($count_result,0,"count");
$pageNumber = ceil($noofrows/$list_max_entries_per_page);
if($pageNumber == 0){
$pageNumber = 1;
}
echo $app_strings['LBL_LIST_OF'].' '.$pageNumber;
?>

View File

@ -0,0 +1,218 @@
<?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('include/logging.php');
require_once('modules/CustomView/CustomView.php');
class ListViewSession {
var $module = null;
var $viewname = null;
var $start = null;
var $sorder = null;
var $sortby = null;
var $page_view = null;
/**initializes ListViewSession
* Portions created by vtigerCRM are Copyright (C) vtigerCRM.
* All Rights Reserved.
*/
function ListViewSession()
{
global $log,$currentModule;
$log->debug("Entering ListViewSession() method ...");
$this->module = $currentModule;
$this->sortby = 'ASC';
$this->start =1;
}
function getCurrentPage($currentModule,$viewId){
if(!empty($_SESSION['lvs'][$currentModule][$viewId]['start'])){
return $_SESSION['lvs'][$currentModule][$viewId]['start'];
}
return 1;
}
function getRequestStartPage(){
$start = $_REQUEST['start'];
if(!is_numeric($start)){
$start = 1;
}
if($start < 1){
$start = 1;
}
$start = ceil($start);
return $start;
}
function getListViewNavigation($currentRecordId){
global $currentModule,$current_user,$adb,$log,$list_max_entries_per_page;
Zend_Json::$useBuiltinEncoderDecoder = true;
$reUseData = false;
$displayBufferRecordCount = 10;
$bufferRecordCount = 15;
if($currentModule == 'Documents'){
$sql = "select folderid from vtiger_notes where notesid=?";
$params = array($currentRecordId);
$result = $adb->pquery($sql,$params);
$folderId = $adb->query_result($result,0,'folderid');
}
$cv = new CustomView();
$viewId = $cv->getViewId($currentModule);
if(!empty($_SESSION[$currentModule.'_DetailView_Navigation'.$viewId])){
$recordNavigationInfo = Zend_Json::decode($_SESSION[$currentModule.'_DetailView_Navigation'.$viewId]);
$pageNumber =0;
if(count($recordNavigationInfo) == 1){
foreach ($recordNavigationInfo as $recordIdList) {
if(in_array($currentRecordId,$recordIdList)){
$reUseData = true;
}
}
}else{
$recordList = array();
$recordPageMapping = array();
foreach ($recordNavigationInfo as $start=>$recordIdList){
foreach ($recordIdList as $index=>$recordId) {
$recordList[] = $recordId;
$recordPageMapping[$recordId] = $start;
if($recordId == $currentRecordId){
$searchKey = count($recordList)-1;
}
}
}
if($searchKey > $displayBufferRecordCount -1 && $searchKey < count($recordList)-$displayBufferRecordCount){
$reUseData= true;
}
}
}
if($reUseData === false){
$recordNavigationInfo = array();
if(!empty($_REQUEST['start'])){
$start = ListViewSession::getRequestStartPage();
}else{
$start = ListViewSession::getCurrentPage($currentModule,$viewId);
}
$startRecord = (($start - 1) * $list_max_entries_per_page) - $bufferRecordCount;
if($startRecord < 0){
$startRecord = 0;
}
$list_query = $_SESSION[$currentModule.'_listquery'];
$instance = CRMEntity::getInstance($currentModule);
$instance->getNonAdminAccessControlQuery($currentModule, $current_user);
vtlib_setup_modulevars($currentModule, $instance);
if($currentModule=='Documents' && !empty($folderId)){
$list_query = preg_replace("/[\n\r\s]+/"," ",$list_query);
$list_query .= " AND vtiger_notes.folderid=$folderId";
$order_by = $instance->getOrderByForFolder($folderId);
$sorder = $instance->getSortOrderForFolder($folderId);
$tablename = getTableNameForField($currentModule,$order_by);
$tablename = (($tablename != '')?($tablename."."):'');
if(!empty($order_by)){
$list_query .= ' ORDER BY '.$tablename.$order_by.' '.$sorder;
}
}
if($start !=1){
$recordCount = ($list_max_entries_per_page+2 * $bufferRecordCount);
}else{
$recordCount = ($list_max_entries_per_page+ $bufferRecordCount);
}
if( $adb->dbType == "pgsql"){
$list_query .= " OFFSET $startRecord LIMIT $recordCount";
}else{
$list_query .= " LIMIT $startRecord, $recordCount";
}
$resultAllCRMIDlist_query=$adb->pquery($list_query,array());
$navigationRecordList = array();
while($forAllCRMID = $adb->fetch_array($resultAllCRMIDlist_query)) {
$navigationRecordList[] = $forAllCRMID[$instance->table_index];
}
$pageCount = 0;
$current = $start;
if($start ==1){
$firstPageRecordCount = $list_max_entries_per_page;
}else{
$firstPageRecordCount = $bufferRecordCount;
$current -=1;
}
$searchKey = array_search($currentRecordId,$navigationRecordList);
$recordNavigationInfo = array();
if($searchKey !== false){
foreach ($navigationRecordList as $index => $recordId) {
if(!is_array($recordNavigationInfo[$current])){
$recordNavigationInfo[$current] = array();
}
if($index == $firstPageRecordCount || $index == ($firstPageRecordCount+$pageCount * $list_max_entries_per_page)){
$current++;
$pageCount++;
}
$recordNavigationInfo[$current][] = $recordId;
}
}
$_SESSION[$currentModule.'_DetailView_Navigation'.$viewId] =
Zend_Json::encode($recordNavigationInfo);
}
return $recordNavigationInfo;
}
function getRequestCurrentPage($currentModule, $query, $viewid, $queryMode = false) {
global $list_max_entries_per_page, $adb;
$start = 1;
if(isset($_REQUEST['query']) && $_REQUEST['query'] == 'true'&& $_REQUEST['start']!="last"){
return ListViewSession::getRequestStartPage();
}
if(!empty($_REQUEST['start'])){
$start = $_REQUEST['start'];
if($start == 'last'){
$count_result = $adb->query( mkCountQuery( $query));
$noofrows = $adb->query_result($count_result,0,"count");
if($noofrows > 0){
$start = ceil($noofrows/$list_max_entries_per_page);
}
}
if(!is_numeric($start)){
$start = 1;
}elseif($start < 1){
$start = 1;
}
$start = ceil($start);
}else if(!empty($_SESSION['lvs'][$currentModule][$viewid]['start'])){
$start = $_SESSION['lvs'][$currentModule][$viewid]['start'];
}
if(!$queryMode) {
$_SESSION['lvs'][$currentModule][$viewid]['start'] = intval($start);
}
return $start;
}
function setSessionQuery($currentModule,$query,$viewid){
if(isset($_SESSION[$currentModule.'_listquery'])){
if($_SESSION[$currentModule.'_listquery'] != $query){
unset($_SESSION[$currentModule.'_DetailView_Navigation'.$viewid]);
}
}
$_SESSION[$currentModule.'_listquery'] = $query;
}
function hasViewChanged($currentModule) {
if(empty($_SESSION['lvs'][$currentModule]['viewname'])) return true;
if(empty($_REQUEST['viewname'])) return false;
if($_REQUEST['viewname'] != $_SESSION['lvs'][$currentModule]['viewname']) return true;
return false;
}
}
?>

View File

@ -0,0 +1,93 @@
<?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
*/
if($ajaxaction == "LOADRELATEDLIST") {
global $relationId;
$relationId = vtlib_purify($_REQUEST['relation_id']);
if(!empty($relationId) && ((int)$relationId) > 0) {
$recordid = vtlib_purify($_REQUEST['record']);
if($_SESSION['rlvs'][$currentModule][$relationId]['currentRecord'] != $recordid) {
$resetCookie = true;
} else {
$resetCookie = false;
}
$_SESSION['rlvs'][$currentModule][$relationId]['currentRecord'] = $recordid;
$actions = vtlib_purify($_REQUEST['actions']);
$header = vtlib_purify($_REQUEST['header']);
$modObj->id = $recordid;
$relationInfo = getRelatedListInfoById($relationId);
$relatedModule = getTabModuleName($relationInfo['relatedTabId']);
$function_name = $relationInfo['functionName'];
$relatedListData = $modObj->$function_name($recordid, getTabid($currentModule),
$relationInfo['relatedTabId'], $actions);
require_once('Smarty_setup.php');
global $theme, $mod_strings, $app_strings;
$theme_path="themes/".$theme."/";
$image_path=$theme_path."images/";
$smarty = new vtigerCRM_Smarty;
// vtlib customization: Related module could be disabled, check it
if(is_array($relatedListData)) {
if( ($relatedModule == "Contacts" || $relatedModule == "Leads" ||
$relatedModule == "Accounts") && $currentModule == 'Campaigns' &&
!$resetCookie) {
//TODO for 5.3 this should be COOKIE not REQUEST, change here else where
// this logic is used for listview checkbox selection propogation.
$checkedRecordIdString = $_REQUEST[$relatedModule.'_all'];
$checkedRecordIdString = rtrim($checkedRecordIdString);
$checkedRecordIdList = explode(';', $checkedRecordIdString);
$relatedListData["checked"]=array();
if (isset($relatedListData['entries'])) {
foreach($relatedListData['entries'] as $key=>$val) {
if(in_array($key,$checkedRecordIdList)) {
$relatedListData["checked"][$key] = 'checked';
} else {
$relatedListData["checked"][$key] = '';
}
}
}
$smarty->assign("SELECTED_RECORD_LIST", $checkedRecordIdString);
} else {
$smarty->assign('RESET_COOKIE', $resetCookie);
}
}
// END
require_once('include/ListView/RelatedListViewSession.php');
RelatedListViewSession::addRelatedModuleToSession($relationId,$header);
$smarty->assign("MOD", $mod_strings);
$smarty->assign("APP", $app_strings);
$smarty->assign("THEME", $theme);
$smarty->assign("IMAGE_PATH", $image_path);
$smarty->assign("ID",$recordid);
$smarty->assign("MODULE",$currentModule);
$smarty->assign("RELATED_MODULE",$relatedModule);
$smarty->assign("HEADER",$header);
$smarty->assign("RELATEDLISTDATA", $relatedListData);
$smarty->display("RelatedListDataContents.tpl");
}
}else if($ajaxaction == "DISABLEMODULE"){
$relationId = vtlib_purify($_REQUEST['relation_id']);
if(!empty($relationId) && ((int)$relationId) > 0) {
$header = vtlib_purify($_REQUEST['header']);
require_once('include/ListView/RelatedListViewSession.php');
RelatedListViewSession::removeRelatedModuleFromSession($relationId,$header);
}
echo "SUCCESS";
}
?>

View File

@ -0,0 +1,116 @@
<?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('include/logging.php');
require_once('include/ListView/ListViewSession.php');
/**initializes Related ListViewSession
* Portions created by vtigerCRM are Copyright (C) vtigerCRM.
* All Rights Reserved.
*/
class RelatedListViewSession {
var $module = null;
var $start = null;
var $sorder = null;
var $sortby = null;
var $page_view = null;
function RelatedListViewSession() {
global $log,$currentModule;
$log->debug("Entering RelatedListViewSession() method ...");
$this->module = $currentModule;
$this->start =1;
}
public static function addRelatedModuleToSession($relationId, $header) {
global $currentModule;
$_SESSION['relatedlist'][$currentModule][$relationId] = $header;
$start = RelatedListViewSession::getRequestStartPage();
RelatedListViewSession::saveRelatedModuleStartPage($relationId, $start);
}
public static function removeRelatedModuleFromSession($relationId, $header) {
global $currentModule;
unset($_SESSION['relatedlist'][$currentModule][$relationId]);
}
public static function getRelatedModulesFromSession() {
global $currentModule;
$allRelatedModuleList = isPresentRelatedLists($currentModule);
$moduleList = array();
if(is_array($_SESSION['relatedlist'][$currentModule])){
foreach ($allRelatedModuleList as $relationId=>$label) {
if(array_key_exists($relationId, $_SESSION['relatedlist'][$currentModule])){
$moduleList[] = $_SESSION['relatedlist'][$currentModule][$relationId];
}
}
}
return $moduleList;
}
public static function saveRelatedModuleStartPage($relationId, $start) {
global $currentModule;
$_SESSION['rlvs'][$currentModule][$relationId]['start'] = $start;
}
public static function getCurrentPage($relationId) {
global $currentModule;
if(!empty($_SESSION['rlvs'][$currentModule][$relationId]['start'])){
return $_SESSION['rlvs'][$currentModule][$relationId]['start'];
}
return 1;
}
public static function getRequestStartPage(){
$start = $_REQUEST['start'];
if(!is_numeric($start)){
$start = 1;
}
if($start < 1){
$start = 1;
}
$start = ceil($start);
return $start;
}
public static function getRequestCurrentPage($relationId, $query) {
global $list_max_entries_per_page, $adb;
$start = 1;
if(!empty($_REQUEST['start'])){
$start = $_REQUEST['start'];
if($start == 'last'){
$count_result = $adb->query( mkCountQuery( $query));
$noofrows = $adb->query_result($count_result,0,"count");
if($noofrows > 0){
$start = ceil($noofrows/$list_max_entries_per_page);
}
}
if(!is_numeric($start)){
$start = 1;
}elseif($start < 1){
$start = 1;
}
$start = ceil($start);
}else {
$start = RelatedListViewSession::getCurrentPage($relationId);
}
return $start;
}
}
?>

95
include/Menu.php Normal file
View File

@ -0,0 +1,95 @@
<?php
/*********************************************************************************
* The contents of this file are subject to the SugarCRM Public License Version 1.1.2
* ("License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is: SugarCRM Open Source
* The Initial Developer of the Original Code is SugarCRM, Inc.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.;
* All Rights Reserved.
* Contributor(s): ______________________________________.
********************************************************************************/
/*********************************************************************************
* $Header$
* Description: TODO To be written.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
********************************************************************************/
global $mod_strings;
global $app_strings;
global $moduleList;
require_once('include/utils/utils.php');
require_once('include/utils/UserInfoUtil.php');
$module_menu_array = Array('Contacts' => $app_strings['LNK_NEW_CONTACT'],
'Leads'=> $app_strings['LNK_NEW_LEAD'],
'Accounts' => $app_strings['LNK_NEW_ACCOUNT'],
'Potentials' => $app_strings['LNK_NEW_OPPORTUNITY'],
'HelpDesk' => $app_strings['LNK_NEW_HDESK'],
'Faq' => $app_strings['LNK_NEW_FAQ'],
'Products' => $app_strings['LNK_NEW_PRODUCT'],
'Documents' => $app_strings['LNK_NEW_NOTE'],
'Emails' => $app_strings['LNK_NEW_EMAIL'],
'Events' => $app_strings['LNK_NEW_EVENT'],
'Tasks' => $app_strings['LNK_NEW_TASK'],
'Vendor' => $app_strings['LNK_NEW_VENDOR'],
'PriceBook' => $app_strings['LNK_NEW_PRICEBOOK'],
'Quotes' => $app_strings['LNK_NEW_QUOTE'],
'PurchaseOrder' => $app_strings['LNK_NEW_PO'],
'SalesOrder' => $app_strings['LNK_NEW_SO'],
'Invoice' => $app_strings['LNK_NEW_INVOICE']
);
$module_menu = Array();
$i= 0;
$add_url = "";
foreach($module_menu_array as $module1 => $label)
{
$add_url='';
$curr_action = 'EditView';
$ret_action = 'DetailView';
if($module1 == 'Events')
{
$module_display = 'Activities';
$add_url = "&activity_mode=Events";
$tabid = getTabid($module1);
}
elseif($module1 == 'Tasks')
{
$module_display = 'Activities';
$add_url = "&activity_mode=Task";
$tabid = getTabid("Activities");
}
else
{
$module_display = $module1;
$tabid = getTabid($module1);
}
if(in_array($module_display, $moduleList))
{
if(isPermitted($module_display,'EditView') == 'yes')
{
$tempArray = Array("index.php?module=".$module_display."&action=".$curr_action."&return_module=".$module_display."&return_action=".$ret_action.$add_url, $label);
$module_menu[$i] = $tempArray;
$i++;
}
}
elseif($module_display == 'Faq')
{
$tempArray = Array("index.php?module=".$module_display."&action=".$curr_action."&return_module=".$module_display."&return_action=".$ret_action.$add_url, $label);
$module_menu[$i] = $tempArray;
$i++;
}
}
?>

View File

@ -0,0 +1,161 @@
<?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('config.php');
require_once('include/logging.php');
require_once('include/language/en_us.lang.php');
require_once('include/database/PearDatabase.php');
require_once('include/ComboStrings.php');
require_once('include/ComboUtil.php');
/**
* Class which handles the population of the combo values
*
*
*/
class PopulateComboValues
{
var $app_list_strings;
/**
* To populate the default combo values for the combo vtiger_tables
* @param $values -- values:: Type string array
* @param $tableName -- tablename:: Type string
*/
function insertComboValues($values, $tableName,$picklistid)
{
global $log;
$log->debug("Entering insertComboValues(".$values.", ".$tableName.") method ...");
global $adb;
//inserting the value in the vtiger_picklistvalues_seq for the getting uniqueID for each picklist values...
$i=0;
foreach ($values as $val => $cal)
{
$picklist_valueid = getUniquePicklistID();
$id = $adb->getUniqueID('vtiger_'.$tableName);
if($val != '')
{
$params = array($id, $val, 1, $picklist_valueid);
$adb->pquery("insert into vtiger_$tableName values(?,?,?,?)", $params);
}
else
{
$params = array($id, '--None--', 1, $picklist_valueid);
$adb->pquery("insert into vtiger_$tableName values(?,?,?,?)", $params);
}
//Default entries for role2picklist relation has been inserted..
$sql="select roleid from vtiger_role";
$role_result = $adb->pquery($sql, array());
$numrow = $adb->num_rows($role_result);
for($k=0; $k < $numrow; $k ++)
{
$roleid = $adb->query_result($role_result,$k,'roleid');
$params = array($roleid, $picklist_valueid, $picklistid, $i);
$adb->pquery("insert into vtiger_role2picklist values(?,?,?,?)", $params);
}
$i++;
}
$log->debug("Exiting insertComboValues method ...");
}
/**
* To populate the combo vtiger_tables at startup time
*/
function create_tables ()
{
global $log;
$log->debug("Entering create_tables () method ...");
global $app_list_strings,$adb;
global $combo_strings;
$comboRes = $adb->query("SELECT distinct fieldname FROM vtiger_field WHERE uitype IN ('15') OR fieldname = 'salutationtype' and vtiger_field.presence in (0,2)");
$noOfCombos = $adb->num_rows($comboRes);
for($i=0; $i<$noOfCombos; $i++)
{
$comTab = $adb->query_result($comboRes, $i, 'fieldname');
$picklistid = $adb->getUniqueID("vtiger_picklist");
$params = array($picklistid, $comTab);
$picklist_qry = "insert into vtiger_picklist values(?,?)";
$adb->pquery($picklist_qry, $params);
$this->insertComboValues($combo_strings[$comTab."_dom"],$comTab,$picklistid);
}
//we have to decide what are all the picklist and picklist values are non editable
//presence = 0 means you cannot edit the picklist value
//presence = 1 means you can edit the picklist value
$noneditable_tables = Array("ticketstatus","taskstatus","eventstatus","faqstatus","quotestage","postatus","sostatus","invoicestatus","activitytype");
$noneditable_values = Array(
"Closed Won"=>"sales_stage",
"Closed Lost"=>"sales_stage",
);
foreach($noneditable_tables as $picklistname)
{
$adb->pquery("update vtiger_".$picklistname." set PRESENCE=0", array());
}
foreach($noneditable_values as $picklistname => $value)
{
$adb->pquery("update vtiger_$value set PRESENCE=0 where $value=?", array($picklistname));
}
$log->debug("Exiting create_tables () method ...");
}
function create_nonpicklist_tables ()
{
global $log;
$log->debug("Entering create_nonpicklist_tables () method ...");
global $app_list_strings,$adb;
global $combo_strings;
// uitype -> 16 - Non standard picklist, 115 - User status, 83 - Tax Class
$comboRes = $adb->query("SELECT distinct fieldname FROM vtiger_field WHERE uitype IN ('16','115','83') AND fieldname NOT IN ('hdnTaxType','email_flag') and vtiger_field.presence in (0,2)");
$noOfCombos = $adb->num_rows($comboRes);
for($i=0; $i<$noOfCombos; $i++)
{
$comTab = $adb->query_result($comboRes, $i, 'fieldname');
$this->insertNonPicklistValues($combo_strings[$comTab."_dom"],$comTab);
}
$log->debug("Exiting create_tables () method ...");
}
function insertNonPicklistValues($values, $tableName)
{
global $log;
$log->debug("Entering insertNonPicklistValues(".$values.", ".$tableName.") method ...");
global $adb;
$i=0;
foreach ($values as $val => $cal)
{
$id = $adb->getUniqueID('vtiger_'.$tableName);
if($val != '')
{
$params = array($id, $val, $i ,1);
}
else
{
$params = array($id, '--None--', $i ,1);
}
$adb->pquery("insert into vtiger_$tableName values(?,?,?,?)", $params);
$i++;
}
$log->debug("Exiting insertNonPicklistValues method ...");
}
}
?>

File diff suppressed because it is too large Load Diff

660
include/RelatedListView.php Normal file
View File

@ -0,0 +1,660 @@
<?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('include/utils/UserInfoUtil.php');
require_once("include/utils/utils.php");
require_once("include/ListView/ListViewSession.php");
require_once("include/ListView/RelatedListViewSession.php");
require_once("include/DatabaseUtil.php");
if(!function_exists('GetRelatedList')) {
function GetRelatedList($module,$relatedmodule,$focus,$query,$button,$returnset,$id='',
$edit_val='',$del_val='',$skipActions=false) {
return GetRelatedListBase($module, $relatedmodule, $focus, $query, $button, $returnset, $id, $edit_val, $del_val, $skipActions);
}
}
/** Function to get related list entries in detailed array format
* @param $module -- modulename:: Type string
* @param $relatedmodule -- relatedmodule:: Type string
* @param $focus -- focus:: Type object
* @param $query -- query:: Type string
* @param $button -- buttons:: Type string
* @param $returnset -- returnset:: Type string
* @param $id -- id:: Type string
* @param $edit_val -- edit value:: Type string
* @param $del_val -- delete value:: Type string
* @returns $related_entries -- related entires:: Type string array
*
*/
function GetRelatedListBase($module,$relatedmodule,$focus,$query,$button,$returnset,$id='',$edit_val='',$del_val='',$skipActions=false)
{
$log = LoggerManager::getLogger('account_list');
$log->debug("Entering GetRelatedList(".$module.",".$relatedmodule.",".get_class($focus).",".$query.",".$button.",".$returnset.",".$edit_val.",".$del_val.") method ...");
require_once('Smarty_setup.php');
require_once("data/Tracker.php");
require_once('include/database/PearDatabase.php');
global $adb;
global $app_strings;
global $current_language;
$current_module_strings = return_module_language($current_language, $module);
global $list_max_entries_per_page;
global $urlPrefix;
global $currentModule;
global $theme;
global $theme_path;
global $theme_path;
global $mod_strings;
// focus_list is the means of passing data to a ListView.
global $focus_list;
$smarty = new vtigerCRM_Smarty;
if (!isset($where)) $where = "";
$button = '<table cellspacing=0 cellpadding=2><tr><td>'.$button.'</td></tr></table>';
// Added to have Purchase Order as form Title
$theme_path="themes/".$theme."/";
$image_path=$theme_path."images/";
$smarty->assign("MOD", $mod_strings);
$smarty->assign("APP", $app_strings);
$smarty->assign("THEME", $theme);
$smarty->assign("IMAGE_PATH",$image_path);
$smarty->assign("MODULE",$relatedmodule);
// We do not have RelatedListView in Detail View mode of Calendar module. So need to skip it.
if ($module!= 'Calendar') {
$focus->initSortByField($relatedmodule);
}
//Retreive the list from Database
//Appending the security parameter Security fix by Don
if($relatedmodule != 'Faq' && $relatedmodule != 'PriceBook'
&& $relatedmodule != 'Vendors' && $relatedmodule != 'Users') {
global $current_user;
$secQuery = getNonAdminAccessControlQuery($relatedmodule, $current_user);
if(strlen($secQuery) > 1) {
$query = appendFromClauseToQuery($query, $secQuery);
}
}
if($relatedmodule == 'Leads') {
$query .= " AND vtiger_leaddetails.converted = 0";
}
if(isset($where) && $where != '')
{
$query .= ' and '.$where;
}
if(!$_SESSION['rlvs'][$module][$relatedmodule])
{
$modObj = new ListViewSession();
$modObj->sortby = $focus->default_order_by;
$modObj->sorder = $focus->default_sort_order;
$_SESSION['rlvs'][$module][$relatedmodule] = get_object_vars($modObj);
}
if(!empty($_REQUEST['order_by'])) {
if(method_exists($focus,getSortOrder))
$sorder = $focus->getSortOrder();
if(method_exists($focus,getOrderBy))
$order_by = $focus->getOrderBy();
if(isset($order_by) && $order_by != '') {
$_SESSION['rlvs'][$module][$relatedmodule]['sorder'] = $sorder;
$_SESSION['rlvs'][$module][$relatedmodule]['sortby'] = $order_by;
}
} elseif($_SESSION['rlvs'][$module][$relatedmodule]) {
$sorder = $_SESSION['rlvs'][$module][$relatedmodule]['sorder'];
$order_by = $_SESSION['rlvs'][$module][$relatedmodule]['sortby'];
} else {
$order_by = $focus->default_order_by;
$sorder = $focus->default_sort_order;
}
//Added by Don for AssignedTo ordering issue in Related Lists
$query_order_by = $order_by;
if($order_by == 'smownerid') {
$userNameSql = getSqlForNameInDisplayFormat(array('first_name'=>'vtiger_users.first_name',
'last_name' => 'vtiger_users.last_name'), 'Users');
$query_order_by = "case when (vtiger_users.user_name not like '') then $userNameSql else vtiger_groups.groupname end ";
} elseif($order_by != 'crmid' && !empty($order_by)) {
$tabname = getTableNameForField($relatedmodule, $order_by);
if($tabname !== '' and $tabname != NULL)
$query_order_by = $tabname.".".$query_order_by;
}
if(!empty($query_order_by)){
$query .= ' ORDER BY '.$query_order_by.' '.$sorder;
}
if($relatedmodule == 'Calendar')
$mod_listquery = "activity_listquery";
else
$mod_listquery = strtolower($relatedmodule)."_listquery";
$_SESSION[$mod_listquery] = $query;
$url_qry .="&order_by=".$order_by."&sorder=".$sorder;
$computeCount = $_REQUEST['withCount'];
if(PerformancePrefs::getBoolean('LISTVIEW_COMPUTE_PAGE_COUNT', false) === true ||
(boolean) $computeCount == true){
//Retreiving the no of rows
if($relatedmodule == "Calendar") {
//for calendar related list, count will increase when we have multiple contacts
//relationship for single activity
$count_query = mkCountQuery($query);
$count_result = $adb->query($count_query);
$noofrows =$adb->query_result($count_result,0,"count");
} else {
$count_query = mkCountQuery($query);
$count_result = $adb->query($count_query);
if($adb->num_rows($count_result) > 0)
$noofrows =$adb->query_result($count_result,0,"count");
else
$noofrows = $adb->num_rows($count_result);
}
}else{
$noofrows = null;
}
//Setting Listview session object while sorting/pagination
if(isset($_REQUEST['relmodule']) && $_REQUEST['relmodule']!='' && $_REQUEST['relmodule'] == $relatedmodule)
{
$relmodule = vtlib_purify($_REQUEST['relmodule']);
if($_SESSION['rlvs'][$module][$relmodule])
{
setSessionVar($_SESSION['rlvs'][$module][$relmodule],$noofrows,$list_max_entries_per_page,$module,$relmodule);
}
}
global $relationId;
$start = RelatedListViewSession::getRequestCurrentPage($relationId, $query);
$navigation_array = VT_getSimpleNavigationValues($start, $list_max_entries_per_page,
$noofrows);
$limit_start_rec = ($start-1) * $list_max_entries_per_page;
if( $adb->dbType == "pgsql")
$list_result = $adb->pquery($query.
" OFFSET $limit_start_rec LIMIT $list_max_entries_per_page", array());
else
$list_result = $adb->pquery($query.
" LIMIT $limit_start_rec, $list_max_entries_per_page", array());
//Retreive the List View Table Header
$id = vtlib_purify($_REQUEST['record']);
$listview_header = getListViewHeader($focus,$relatedmodule,'',$sorder,$order_by,$id,'',$module,$skipActions);//"Accounts");
if ($noofrows > 15) {
$smarty->assign('SCROLLSTART','<div style="overflow:auto;height:315px;width:100%;">');
$smarty->assign('SCROLLSTOP','</div>');
}
$smarty->assign("LISTHEADER", $listview_header);
if($module == 'PriceBook' && $relatedmodule == 'Products') {
$listview_entries = getListViewEntries($focus,$relatedmodule,$list_result,$navigation_array,'relatedlist',$returnset,$edit_val,$del_val,'','','','',$skipActions);
}
if($module == 'Products' && $relatedmodule == 'PriceBook') {
$listview_entries = getListViewEntries($focus,$relatedmodule,$list_result,$navigation_array,'relatedlist',$returnset,'EditListPrice','DeletePriceBookProductRel','','','','',$skipActions);
} elseif($relatedmodule == 'SalesOrder') {
$listview_entries = getListViewEntries($focus,$relatedmodule,$list_result,$navigation_array,'relatedlist',$returnset,'SalesOrderEditView','DeleteSalesOrder','','','','',$skipActions);
}else {
$listview_entries = getListViewEntries($focus,$relatedmodule,$list_result,$navigation_array,'relatedlist',$returnset,$edit_val,$del_val,'','','','',$skipActions);
}
$navigationOutput = Array();
$navigationOutput[] = getRecordRangeMessage($list_result, $limit_start_rec,$noofrows);
if(empty($id) && !empty($_REQUEST['record'])) $id = vtlib_purify($_REQUEST['record']);
$navigationOutput[] = getRelatedTableHeaderNavigation($navigation_array, $url_qry,$module,$relatedmodule,$id);
$related_entries = array('header'=>$listview_header,'entries'=>$listview_entries,'navigation'=>$navigationOutput);
$log->debug("Exiting GetRelatedList method ...");
return $related_entries;
}
/** Function to get related list entries in detailed array format
* @param $parentmodule -- parentmodulename:: Type string
* @param $query -- query:: Type string
* @param $id -- id:: Type string
* @returns $entries_list -- entries list:: Type string array
*
*/
function getAttachmentsAndNotes($parentmodule,$query,$id,$sid='')
{
global $log;
$log->debug("Entering getAttachmentsAndNotes(".$parentmodule.",".$query.",".$id.",".$sid.") method ...");
global $theme;
$list = '<script>
function confirmdelete(url)
{
if(confirm("'.$app_strings['ARE_YOU_SURE'].'"))
{
document.location.href=url;
}
}
</script>';
$theme_path="themes/".$theme."/";
$image_path=$theme_path."images/";
global $adb,$current_user;
global $mod_strings;
global $app_strings, $listview_max_textlength;
$result=$adb->query($query);
$noofrows = $adb->num_rows($result);
$_SESSION['Documents_listquery'] = $query;
$header[] = $app_strings['LBL_TITLE'];
$header[] = $app_strings['LBL_DESCRIPTION'];
$header[] = $app_strings['LBL_ATTACHMENTS'];
$header[] = $app_strings['LBL_ASSIGNED_TO'];
$header[] = $app_strings['LBL_ACTION'];
if($result)
{
while($row = $adb->fetch_array($result))
{
if($row['activitytype'] == 'Attachments') {
$query1="select setype,createdtime from vtiger_crmentity where crmid=?";
$params1 = array($row['attachmentsid']);
} else {
$query1="select setype,createdtime from vtiger_crmentity where crmid=?";
$params1 = array($row['crmid']);
}
$query1 .=" order by createdtime desc";
$res=$adb->pquery($query1, $params1);
$num_rows = $adb->num_rows($res);
for($i=0; $i<$num_rows; $i++)
{
$setype = $adb->query_result($res,$i,'setype');
$createdtime = $adb->query_result($res,$i,'createdtime');
}
if(($setype != "Products Image") && ($setype != "Contacts Image"))
{
$entries = Array();
if(trim($row['activitytype']) == 'Documents')
{
$module = 'Documents';
$editaction = 'EditView';
$deleteaction = 'Delete';
}
elseif($row['activitytype'] == 'Attachments')
{
$module = 'uploads';
$editaction = 'upload';
$deleteaction = 'deleteattachments';
}
if($module == 'Documents')
{
$entries[] = '<a href="index.php?module='.$module.'&action=DetailView&return_module='.$parentmodule.'&return_action='.$return_action.'&record='.$row["crmid"].'&filename='.$row['filename'].'&fileid='.$row['attachmentsid'].'&return_id='.vtlib_purify($_REQUEST["record"]).'&parenttab='.vtlib_purify($_REQUEST["parenttab"]).'">'.textlength_check($row['title']).'</a>';
}
elseif($module == 'uploads')
{
$entries[] = $row['title'];
}
if((getFieldVisibilityPermission('Documents', $current_user->id, 'notecontent') == '0') || $row['activitytype'] == 'Documents')
{
$row['description'] = preg_replace("/(<\/?)(\w+)([^>]*>)/i","",$row['description']);
if($listview_max_textlength && (strlen($row['description']) > $listview_max_textlength))
{
$row['description'] = substr($row['description'],0,$listview_max_textlength).'...';
}
$entries[] = nl2br($row['description']);
}
else
$entries[] = " <font color ='red' >" .$app_strings['LBL_NOT_ACCESSIBLE']."</font>";
$attachmentname = $row['filename'];//explode('_',$row['filename'],2);
if((getFieldVisibilityPermission('Documents', $current_user->id, 'filename') == 0))
{
global $adb;
$prof_id = fetchUserProfileId($current_user->id);
$modulepermissionQuery = "select permissions from vtiger_profile2tab where tabid=8 and profileid= ?";
$modulepermissionresult = $adb->pquery($modulepermissionQuery,array($prof_id));
$moduleviewpermission = $adb->query_result($modulepermissionresult,0,'permissions');
$folderQuery = 'select folderid,filelocationtype,filestatus,filename from vtiger_notes where notesid = ?';
$folderresult = $adb->pquery($folderQuery,array($row["crmid"]));
$folder_id = $adb->query_result($folderresult,0,'folderid');
$download_type = $adb->query_result($folderresult,0,'filelocationtype');
$filestatus = $adb->query_result($folderresult,0,'filestatus');
$filename = $adb->query_result($folderresult,0,'filename');
$fileQuery = $adb->pquery("select attachmentsid from vtiger_seattachmentsrel where crmid = ?",array($row['crmid']));
$fileid = $adb->query_result($fileQuery,0,'attachmentsid');
if($moduleviewpermission == 0)
{
if($download_type == 'I' )
{
if($filestatus == 1 )
$entries[] = '<a href="index.php?module=Documents&action=DownloadFile&fileid='.$fileid.'&folderid='.$folder_id.'">'.textlength_check($attachmentname).'</a>';
elseif(isset($attachmentname) && $attachmentname != '')
$entries[] = textlength_check($attachmentname);
else
$entries[] = ' --';
}
elseif($download_type == 'E' )
{
if($filestatus == 1)
$entries[] = '<a target="_blank" href="'.$filename.'" onClick="javascript:dldCntIncrease('.$row['crmid'].');">'.textlength_check($attachmentname).'</a>';
elseif(isset($attachmentname) && $attachmentname != '')
$entries[] = textlength_check($attachmentname);
else
$entries[] = ' --';
}
else{
$entries[] = ' --';
}
}
else
{
if(isset($attachmentname))
$entries[] = textlength_check($attachmentname);
else
$entries[] = ' --';
}
}
else
$entries[]='';
$assignedToQuery = $adb->pquery('SELECT smownerid FROM vtiger_crmentity WHERE crmid = ?',array($row['crmid']));
$assignedTo = $adb->query_result($assignedToQuery,0,'smownerid');
if($assignedTo != '' ){
$entries[] = $assignedTo;
}
$del_param = 'index.php?module='.$module.'&action='.$deleteaction.'&return_module='.$parentmodule.'&return_action='.vtlib_purify($_REQUEST['action']).'&record='.$row["crmid"].'&return_id='.vtlib_purify($_REQUEST["record"]).'&parenttab='.vtlib_purify($_REQUEST["parenttab"]);
if($module == 'Documents')
{
$edit_param = 'index.php?module='.$module.'&action='.$editaction.'&return_module='.$parentmodule.'&return_action='.vtlib_purify($_REQUEST['action']).'&record='.$row["crmid"].'&filename='.$row['filename'].'&fileid='.$row['attachmentsid'].'&return_id='.vtlib_purify($_REQUEST["record"]).'&parenttab='.vtlib_purify($_REQUEST["parenttab"]);
$entries[] .= '<a href="'.$edit_param.'">'.$app_strings['LNK_EDIT'].'</a> | <a href=\'javascript:confirmdelete("'.$del_param.'")\'>'.$app_strings['LNK_DELETE'].'</a>';
}
else
{
$entries[] = '<a href=\'javascript:confirmdelete("'.$del_param.'")\'>'.$app_strings['LNK_DELETE'].'</a>';
}
$entries_list[] = $entries;
}
}
}
if($entries_list != '')
$return_data = array('header'=>$header,'entries'=>$entries_list);
$log->debug("Exiting getAttachmentsAndNotes method ...");
return $return_data;
}
/** Function to get related list entries in detailed array format
* @param $parentmodule -- parentmodulename:: Type string
* @param $query -- query:: Type string
* @param $id -- id:: Type string
* @returns $return_data -- return data:: Type string array
*
*/
function getHistory($parentmodule,$query,$id)
{
global $log;
$log->debug("Entering getHistory(".$parentmodule.",".$query.",".$id.") method ...");
$parentaction = vtlib_purify($_REQUEST['action']);
global $theme;
$theme_path="themes/".$theme."/";
$image_path=$theme_path."images/";
global $adb;
global $mod_strings;
global $app_strings;
//Appending the security parameter
global $current_user;
$rel_tab_id = getTabid("Calendar");
global $current_user;
require('user_privileges/user_privileges_'.$current_user->id.'.php');
require('user_privileges/sharing_privileges_'.$current_user->id.'.php');
$tab_id = getTabid('Calendar');
if($is_admin == false && $profileGlobalPermission[1] == 1 && $profileGlobalPermission[2] == 1 && $defaultOrgSharingPermission[$tab_id] == 3)
{
$sec_parameter=getListViewSecurityParameter('Calendar');
$query .= ' '.$sec_parameter;
}
$query.= ' '."ORDER BY vtiger_activity.date_start DESC,vtiger_activity.time_start DESC";
$result=$adb->query($query);
$noofrows = $adb->num_rows($result);
if($noofrows == 0)
{
//There is no entries for history
}
else
{
//Form the header columns
$header[] = $app_strings['LBL_TYPE'];
$header[] = $app_strings['LBL_SUBJECT'];
$header[] = $app_strings['LBL_RELATED_TO'];
$header[] = $app_strings['LBL_START_DATE']." & ".$app_strings['LBL_TIME'];
$header[] = $app_strings['LBL_END_DATE']." & ".$app_strings['LBL_TIME'];
//$header[] = $app_strings['LBL_DESCRIPTION'];
$header[] = $app_strings['LBL_STATUS'];
$header[] = $app_strings['LBL_ASSIGNED_TO'];
$i = 1;
while($row = $adb->fetch_array($result))
{
$entries = Array();
if($row['activitytype'] == 'Task')
{
$activitymode = 'Task';
$icon = 'Tasks.gif';
$status = $row['status'];
$status = $app_strings[$status];
}
else
{
$activitymode = 'Events';
$icon = 'Activities.gif';
$status = $row['eventstatus'];
$status = $app_strings[$status];
}
$typeofactivity = $row['activitytype'];
$typeofactivity = getTranslatedString($typeofactivity, 'Calendar');
$entries[] = $typeofactivity;
$activity = '<a href="index.php?module=Calendar&action=DetailView&return_module='.$parentmodule.'&return_action=DetailView&record='.$row["activityid"] .'&activity_mode='.$activitymode.'&return_id='.vtlib_purify($_REQUEST['record']).'&parenttab='.vtlib_purify($_REQUEST['parenttab']).'">'.$row['subject'].'</a></td>';
$entries[] = $activity;
$parentname = getRelatedTo('Calendar',$result,$i-1);
$entries[] = $parentname;
$date = new DateTimeField($row['date_start']." ".$row['time_start']);
$entries[] = $date->getDisplayDateTimeValue();
$date = new DateTimeField($row['due_date']." ".$row['time_end']);
$entries[] = $date->getDisplayDate();
$entries[] = $status;
if($row['user_name'] == null && $row['groupname'] != null)
{
$entries[] = $row['groupname'];
}
else
{
$entries[] = $row['user_name'];
}
$i++;
$entries_list[] = $entries;
}
$return_data = array('header'=>$header,'entries'=>$entries_list);
$log->debug("Exiting getHistory method ...");
return $return_data;
}
}
/** Function to display the Products which are related to the PriceBook
* @param string $query - query to get the list of products which are related to the current PriceBook
* @param object $focus - PriceBook object which contains all the information of the current PriceBook
* @param string $returnset - return_module, return_action and return_id which are sequenced with & to pass to the URL which is optional
* return array $return_data which will be formed like array('header'=>$header,'entries'=>$entries_list) where as $header contains all the header columns and $entries_list will contain all the Product entries
*/
function getPriceBookRelatedProducts($query,$focus,$returnset='')
{
global $log;
$log->debug("Entering getPriceBookRelatedProducts(".$query.",".get_class($focus).",".$returnset.") method ...");
global $adb;
global $app_strings;
global $mod_strings;
global $current_language,$current_user;
$current_module_strings = return_module_language($current_language, 'PriceBook');
global $list_max_entries_per_page;
global $urlPrefix;
global $theme;
$pricebook_id = vtlib_purify($_REQUEST['record']);
$theme_path="themes/".$theme."/";
$image_path=$theme_path."images/";
$computeCount = $_REQUEST['withCount'];
if(PerformancePrefs::getBoolean('LISTVIEW_COMPUTE_PAGE_COUNT', false) === true ||
((boolean) $computeCount) == true){
$noofrows = $adb->query_result($adb->query(mkCountQuery($query)),0,'count');
}else{
$noofrows = null;
}
$module = 'PriceBooks';
$relatedmodule = 'Products';
if(!$_SESSION['rlvs'][$module][$relatedmodule])
{
$modObj = new ListViewSession();
$modObj->sortby = $focus->default_order_by;
$modObj->sorder = $focus->default_sort_order;
$_SESSION['rlvs'][$module][$relatedmodule] = get_object_vars($modObj);
}
if(isset($_REQUEST['relmodule']) && $_REQUEST['relmodule']!='' && $_REQUEST['relmodule'] == $relatedmodule) {
$relmodule = vtlib_purify($_REQUEST['relmodule']);
if($_SESSION['rlvs'][$module][$relmodule]) {
setSessionVar($_SESSION['rlvs'][$module][$relmodule],$noofrows,$list_max_entries_per_page,$module,$relmodule);
}
}
global $relationId;
$start = RelatedListViewSession::getRequestCurrentPage($relationId, $query);
$navigation_array = VT_getSimpleNavigationValues($start, $list_max_entries_per_page,
$noofrows);
$limit_start_rec = ($start-1) * $list_max_entries_per_page;
if( $adb->dbType == "pgsql")
$list_result = $adb->pquery($query.
" OFFSET $limit_start_rec LIMIT $list_max_entries_per_page", array());
else
$list_result = $adb->pquery($query.
" LIMIT $limit_start_rec, $list_max_entries_per_page", array());
$header=array();
$header[]=$mod_strings['LBL_LIST_PRODUCT_NAME'];
if(getFieldVisibilityPermission('Products', $current_user->id, 'productcode') == '0')
$header[]=$mod_strings['LBL_PRODUCT_CODE'];
if(getFieldVisibilityPermission('Products', $current_user->id, 'unit_price') == '0')
$header[]=$mod_strings['LBL_PRODUCT_UNIT_PRICE'];
$header[]=$mod_strings['LBL_PB_LIST_PRICE'];
if(isPermitted("PriceBooks","EditView","") == 'yes' || isPermitted("PriceBooks","Delete","") == 'yes')
$header[]=$mod_strings['LBL_ACTION'];
$currency_id = $focus->column_fields['currency_id'];
$numRows = $adb->num_rows($list_result);
for($i=0; $i<$numRows; $i++) {
$entity_id = $adb->query_result($list_result,$i,"crmid");
$unit_price = $adb->query_result($list_result,$i,"unit_price");
if($currency_id != null) {
$prod_prices = getPricesForProducts($currency_id, array($entity_id));
$unit_price = $prod_prices[$entity_id];
}
$listprice = $adb->query_result($list_result,$i,"listprice");
$field_name=$entity_id."_listprice";
$entries = Array();
$entries[] = textlength_check($adb->query_result($list_result,$i,"productname"));
if(getFieldVisibilityPermission('Products', $current_user->id, 'productcode') == '0')
$entries[] = $adb->query_result($list_result,$i,"productcode");
if(getFieldVisibilityPermission('Products', $current_user->id, 'unit_price') == '0')
$entries[] = CurrencyField::convertToUserFormat($unit_price, null, true);
$entries[] = CurrencyField::convertToUserFormat($listprice, null, true);
$action = "";
if(isPermitted("PriceBooks","EditView","") == 'yes' && isPermitted('Products', 'EditView', $entity_id) == 'yes') {
$action .= '<img style="cursor:pointer;" src="'. vtiger_imageurl('editfield.gif', $theme).'" border="0" onClick="fnvshobj(this,\'editlistprice\'),editProductListPrice(\''.$entity_id.'\',\''.$pricebook_id.'\',\''.$listprice.'\')" alt="'.$app_strings["LBL_EDIT_BUTTON"].'" title="'.$app_strings["LBL_EDIT_BUTTON"].'"/>';
} else {
$action .= '<img src="'. vtiger_imageurl('blank.gif', $theme).'" border="0" />';
}
if(isPermitted("PriceBooks","Delete","") == 'yes' && isPermitted('Products', 'Delete', $entity_id) == 'yes') {
if($action != "")
$action .= '&nbsp;|&nbsp;';
$action .= '<img src="'. vtiger_imageurl('delete.gif', $theme).'" onclick="if(confirm(\''.$app_strings['ARE_YOU_SURE'].'\')) deletePriceBookProductRel('.$entity_id.','.$pricebook_id.');" alt="'.$app_strings["LBL_DELETE"].'" title="'.$app_strings["LBL_DELETE"].'" style="cursor:pointer;" border="0">';
}
if($action != "")
$entries[] = $action;
$entries_list[] = $entries;
}
$navigationOutput[] = getRecordRangeMessage($list_result, $limit_start_rec,$noofrows);
$navigationOutput[] = getRelatedTableHeaderNavigation($navigation_array, '',$module,
$relatedmodule,$focus->id);
$return_data = array('header'=>$header,'entries'=>$entries_list,'navigation'=>$navigationOutput);
$log->debug("Exiting getPriceBookRelatedProducts method ...");
return $return_data;
}
function CheckFieldPermission($fieldname,$module) {
global $current_user,$adb;
require('user_privileges/user_privileges_'.$current_user->id.'.php');
if($fieldname == '' || $module == '') {
return "false";
}
if(getFieldVisibilityPermission($module, $current_user->id, $fieldname) == '0') {
return "true";
}
return "false";
}
function CheckColumnPermission($tablename, $columnname, $module)
{
global $adb;
$res = $adb->pquery("select fieldname from vtiger_field where tablename=? and columnname=? and vtiger_field.presence in (0,2)", array($tablename, $columnname));
$fieldname = $adb->query_result($res, 0, 'fieldname');
return CheckFieldPermission($fieldname, $module);
}
?>

View File

@ -0,0 +1,31 @@
<?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.
*************************************************************************************/
function vtws_getchallenge($username){
global $adb;
$user = new Users();
$userid = $user->retrieve_user_id($username);
$authToken = uniqid();
$servertime = time();
$expireTime = time()+(60*5);
$sql = "delete from vtiger_ws_userauthtoken where userid=?";
$adb->pquery($sql,array($userid));
$sql = "insert into vtiger_ws_userauthtoken(userid,token,expireTime) values (?,?,?)";
$adb->pquery($sql,array($userid,$authToken,$expireTime));
return array("token"=>$authToken,"serverTime"=>$servertime,"expireTime"=>$expireTime);
}
?>

View File

@ -0,0 +1,70 @@
<?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 Musavir Ahmed Khan<musavir at vtiger.com>
*/
/**
* @param WebserviceId $id
* @param String $oldPassword
* @param String $newPassword
* @param String $confirmPassword
* @param Users $user
*
*/
function vtws_changePassword($id, $oldPassword, $newPassword, $confirmPassword, $user) {
vtws_preserveGlobal('current_user',$user);
$idComponents = vtws_getIdComponents($id);
if($idComponents[1] == $user->id || is_admin($user)) {
$newUser = new Users();
$newUser->retrieveCurrentUserInfoFromFile($idComponents[1]);
if(!is_admin($user)) {
if(empty($oldPassword)) {
throw new WebServiceException(WebServiceErrorCode::$INVALIDOLDPASSWORD,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$INVALIDOLDPASSWORD));
}
if(!$user->verifyPassword($oldPassword)) {
throw new WebServiceException(WebServiceErrorCode::$INVALIDOLDPASSWORD,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$INVALIDOLDPASSWORD));
}
}
if(strcmp($newPassword, $confirmPassword) === 0) {
$db = PearDatabase::getInstance();
$db->dieOnError = true;
$db->startTransaction();
$success = $newUser->change_password($oldPassword, $newPassword, false);
$error = $db->hasFailedTransaction();
$db->completeTransaction();
if($error) {
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
if(!$success) {
throw new WebServiceException(WebServiceErrorCode::$CHANGEPASSWORDFAILURE,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$CHANGEPASSWORDFAILURE));
}
} else {
throw new WebServiceException(WebServiceErrorCode::$CHANGEPASSWORDFAILURE,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$CHANGEPASSWORDFAILURE));
}
VTWS_PreserveGlobal::flush();
return array('message' => 'Changed password successfully');
}
}
?>

View File

@ -0,0 +1,266 @@
<?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 'include/Webservices/Retrieve.php';
require_once 'include/Webservices/Create.php';
require_once 'include/Webservices/Delete.php';
require_once 'include/Webservices/DescribeObject.php';
function vtws_convertlead($entityvalues, $user) {
global $adb, $log;
if (empty($entityvalues['assignedTo'])) {
$entityvalues['assignedTo'] = vtws_getWebserviceEntityId('Users', $user->id);
}
if (empty($entityvalues['transferRelatedRecordsTo'])) {
$entityvalues['transferRelatedRecordsTo'] = 'Contacts';
}
$leadObject = VtigerWebserviceObject::fromName($adb, 'Leads');
$handlerPath = $leadObject->getHandlerPath();
$handlerClass = $leadObject->getHandlerClass();
require_once $handlerPath;
$leadHandler = new $handlerClass($leadObject, $user, $adb, $log);
$leadInfo = vtws_retrieve($entityvalues['leadId'], $user);
$sql = "select converted from vtiger_leaddetails where converted = 1 and leadid=?";
$leadIdComponents = vtws_getIdComponents($entityvalues['leadId']);
$result = $adb->pquery($sql, array($leadIdComponents[1]));
if ($result === false) {
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_' .
WebServiceErrorCode::$DATABASEQUERYERROR));
}
$rowCount = $adb->num_rows($result);
if ($rowCount > 0) {
throw new WebServiceException(WebServiceErrorCode::$LEAD_ALREADY_CONVERTED,
"Lead is already converted");
}
$entityIds = array();
$availableModules = array('Accounts', 'Contacts', 'Potentials');
if (!(($entityvalues['entities']['Accounts']['create']) || ($entityvalues['entities']['Contacts']['create']))) {
return null;
}
foreach ($availableModules as $entityName) {
if ($entityvalues['entities'][$entityName]['create']) {
$entityvalue = $entityvalues['entities'][$entityName];
$entityObject = VtigerWebserviceObject::fromName($adb, $entityvalue['name']);
$handlerPath = $entityObject->getHandlerPath();
$handlerClass = $entityObject->getHandlerClass();
require_once $handlerPath;
$entityHandler = new $handlerClass($entityObject, $user, $adb, $log);
$entityObjectValues = array();
$entityObjectValues['assigned_user_id'] = $entityvalues['assignedTo'];
$entityObjectValues = vtws_populateConvertLeadEntities($entityvalue, $entityObjectValues, $entityHandler, $leadHandler, $leadInfo);
//update potential related to property
if ($entityvalue['name'] == 'Potentials') {
if (!empty($entityIds['Accounts'])) {
$entityObjectValues['related_to'] = $entityIds['Accounts'];
} else {
$entityObjectValues['related_to'] = $entityIds['Contacts'];
}
}
//update the contacts relation
if ($entityvalue['name'] == 'Contacts') {
if (!empty($entityIds['Accounts'])) {
$entityObjectValues['account_id'] = $entityIds['Accounts'];
}
}
try {
$create = true;
if ($entityvalue['name'] == 'Accounts') {
$sql = "SELECT vtiger_account.accountid FROM vtiger_account,vtiger_crmentity WHERE vtiger_crmentity.crmid=vtiger_account.accountid AND vtiger_account.accountname=? AND vtiger_crmentity.deleted=0";
$result = $adb->pquery($sql, array($entityvalue['accountname']));
if ($adb->num_rows($result) > 0) {
$entityIds[$entityName] = vtws_getWebserviceEntityId('Accounts', $adb->query_result($result, 0, 'accountid'));
$create = false;
}
}
if ($create) {
$entityRecord = vtws_create($entityvalue['name'], $entityObjectValues, $user);
$entityIds[$entityName] = $entityRecord['id'];
}
} catch (Exception $e) {
return null;
}
}
}
try {
$accountIdComponents = vtws_getIdComponents($entityIds['Accounts']);
$accountId = $accountIdComponents[1];
$contactIdComponents = vtws_getIdComponents($entityIds['Contacts']);
$contactId = $contactIdComponents[1];
if (!empty($accountId) && !empty($contactId) && !empty($entityIds['Potentials'])) {
$potentialIdComponents = vtws_getIdComponents($entityIds['Potentials']);
$potentialId = $potentialIdComponents[1];
$sql = "insert into vtiger_contpotentialrel values(?,?)";
$result = $adb->pquery($sql, array($contactId, $potentialIdComponents[1]));
if ($result === false) {
throw new WebServiceException(WebServiceErrorCode::$FAILED_TO_CREATE_RELATION,
"Failed to related Contact with the Potential");
}
}
$transfered = vtws_convertLeadTransferHandler($leadIdComponents, $entityIds, $entityvalues);
$relatedIdComponents = vtws_getIdComponents($entityIds[$entityvalues['transferRelatedRecordsTo']]);
vtws_getRelatedActivities($leadIdComponents[1], $accountId, $contactId, $relatedIdComponents[1]);
vtws_updateConvertLeadStatus($entityIds, $entityvalues['leadId'], $user);
} catch (Exception $e) {
foreach ($entityIds as $entity => $id) {
vtws_delete($id, $user);
}
return null;
}
return $entityIds;
}
/*
* populate the entity fields with the lead info.
* if mandatory field is not provided populate with '????'
* returns the entity array.
*/
function vtws_populateConvertLeadEntities($entityvalue, $entity, $entityHandler, $leadHandler, $leadinfo) {
global $adb, $log;
$column;
$entityName = $entityvalue['name'];
$sql = "SELECT * FROM vtiger_convertleadmapping";
$result = $adb->pquery($sql, array());
if ($adb->num_rows($result)) {
switch ($entityName) {
case 'Accounts':$column = 'accountfid';
break;
case 'Contacts':$column = 'contactfid';
break;
case 'Potentials':$column = 'potentialfid';
break;
default:$column = 'leadfid';
break;
}
$leadFields = $leadHandler->getMeta()->getModuleFields();
$entityFields = $entityHandler->getMeta()->getModuleFields();
$row = $adb->fetch_array($result);
$count = 1;
do {
$entityField = vtws_getFieldfromFieldId($row[$column], $entityFields);
if ($entityField == null) {
//user doesn't have access so continue.TODO update even if user doesn't have access
continue;
}
$leadField = vtws_getFieldfromFieldId($row['leadfid'], $leadFields);
if ($leadField == null) {
//user doesn't have access so continue.TODO update even if user doesn't have access
continue;
}
$leadFieldName = $leadField->getFieldName();
$entityFieldName = $entityField->getFieldName();
$entity[$entityFieldName] = $leadinfo[$leadFieldName];
$count++;
} while ($row = $adb->fetch_array($result));
foreach ($entityvalue as $fieldname => $fieldvalue) {
if (!empty($fieldvalue)) {
$entity[$fieldname] = $fieldvalue;
}
}
$entity = vtws_validateConvertLeadEntityMandatoryValues($entity, $entityHandler, $leadinfo, $entityName);
}
return $entity;
}
function vtws_validateConvertLeadEntityMandatoryValues($entity, $entityHandler, $leadinfo, $module) {
$mandatoryFields = $entityHandler->getMeta()->getMandatoryFields();
foreach ($mandatoryFields as $field) {
if (empty($entity[$field])) {
$fieldInfo = vtws_getConvertLeadFieldInfo($module, $field);
if (($fieldInfo['type']['name'] == 'picklist' || $fieldInfo['type']['name'] == 'multipicklist'
|| $fieldInfo['type']['name'] == 'date' || $fieldInfo['type']['name'] == 'datetime')
&& ($fieldInfo['editable'] == true)) {
$entity[$field] = $fieldInfo['default'];
} else {
$entity[$field] = '????';
}
}
}
return $entity;
}
function vtws_getConvertLeadFieldInfo($module, $fieldname) {
global $adb, $log, $current_user;
$describe = vtws_describe($module, $current_user);
foreach ($describe['fields'] as $index => $fieldInfo) {
if ($fieldInfo['name'] == $fieldname) {
return $fieldInfo;
}
}
return false;
}
//function to handle the transferring of related records for lead
function vtws_convertLeadTransferHandler($leadIdComponents, $entityIds, $entityvalues) {
try {
$entityidComponents = vtws_getIdComponents($entityIds[$entityvalues['transferRelatedRecordsTo']]);
vtws_transferLeadRelatedRecords($leadIdComponents[1], $entityidComponents[1], $entityvalues['transferRelatedRecordsTo']);
} catch (Exception $e) {
return false;
}
return true;
}
function vtws_updateConvertLeadStatus($entityIds, $leadId, $user) {
global $adb, $log;
$leadIdComponents = vtws_getIdComponents($leadId);
if ($entityIds['Accounts'] != '' || $entityIds['Contacts'] != '') {
$sql = "UPDATE vtiger_leaddetails SET converted = 1 where leadid=?";
$result = $adb->pquery($sql, array($leadIdComponents[1]));
if ($result === false) {
throw new WebServiceException(WebServiceErrorCode::$FAILED_TO_MARK_CONVERTED,
"Failed mark lead converted");
}
//updating the campaign-lead relation --Minnie
$sql = "DELETE FROM vtiger_campaignleadrel WHERE leadid=?";
$adb->pquery($sql, array($leadIdComponents[1]));
$sql = "DELETE FROM vtiger_tracker WHERE item_id=?";
$adb->pquery($sql, array($leadIdComponents[1]));
//update the modifiedtime and modified by information for the record
$leadModifiedTime = $adb->formatDate(date('Y-m-d H:i:s'), true);
$crmentityUpdateSql = "UPDATE vtiger_crmentity SET modifiedtime=?, modifiedby=? WHERE crmid=?";
$adb->pquery($crmentityUpdateSql, array($leadModifiedTime, $user->id, $leadIdComponents[1]));
}
}
?>

View File

@ -0,0 +1,85 @@
<?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.
************************************************************************************ */
function vtws_create($elementType, $element, $user) {
$types = vtws_listtypes(null, $user);
if (!in_array($elementType, $types['types'])) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to perform the operation is denied");
}
global $log, $adb;
// Cache the instance for re-use
if(!isset($vtws_create_cache[$elementType]['webserviceobject'])) {
$webserviceObject = VtigerWebserviceObject::fromName($adb,$elementType);
$vtws_create_cache[$elementType]['webserviceobject'] = $webserviceObject;
} else {
$webserviceObject = $vtws_create_cache[$elementType]['webserviceobject'];
}
// END
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject, $user, $adb, $log);
$meta = $handler->getMeta();
if ($meta->hasWriteAccess() !== true) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to write is denied");
}
$referenceFields = $meta->getReferenceFieldDetails();
foreach ($referenceFields as $fieldName => $details) {
if (isset($element[$fieldName]) && strlen($element[$fieldName]) > 0) {
$ids = vtws_getIdComponents($element[$fieldName]);
$elemTypeId = $ids[0];
$elemId = $ids[1];
$referenceObject = VtigerWebserviceObject::fromId($adb, $elemTypeId);
if (!in_array($referenceObject->getEntityName(), $details)) {
throw new WebServiceException(WebServiceErrorCode::$REFERENCEINVALID,
"Invalid reference specified for $fieldName");
}
if ($referenceObject->getEntityName() == 'Users') {
if(!$meta->hasAssignPrivilege($element[$fieldName])) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Cannot assign record to the given user");
}
}
if (!in_array($referenceObject->getEntityName(), $types['types']) && $referenceObject->getEntityName() != 'Users') {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,
"Permission to access reference type is denied" . $referenceObject->getEntityName());
}
} else if ($element[$fieldName] !== NULL) {
unset($element[$fieldName]);
}
}
if ($meta->hasMandatoryFields($element)) {
$ownerFields = $meta->getOwnerFields();
if (is_array($ownerFields) && sizeof($ownerFields) > 0) {
foreach ($ownerFields as $ownerField) {
if (isset($element[$ownerField]) && $element[$ownerField] !== null &&
!$meta->hasAssignPrivilege($element[$ownerField])) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Cannot assign record to the given user");
}
}
}
$entity = $handler->create($elementType, $element);
VTWS_PreserveGlobal::flush();
return $entity;
} else {
return null;
}
}
?>

View File

@ -0,0 +1,277 @@
<?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 DataTransform{
public static $recordString = "record_id";
public static $recordModuleString = 'record_module';
function sanitizeDataWithColumn($row,$meta){
$newRow = array();
if(isset($row['count(*)'])){
return DataTransform::sanitizeDataWithCountColumn($row,$meta);
}
$fieldColumnMapping = $meta->getFieldColumnMapping();
$columnFieldMapping = array_flip($fieldColumnMapping);
foreach($row as $col=>$val){
if(array_key_exists($col,$columnFieldMapping))
$newRow[$columnFieldMapping[$col]] = $val;
}
$newRow = DataTransform::sanitizeData($newRow,$meta,true);
return $newRow;
}
function sanitizeDataWithCountColumn($row,$meta){
$newRow = array();
foreach($row as $col=>$val){
$newRow['count'] = $val;
}
return $newRow;
}
function filterAndSanitize($row,$meta){
$row = DataTransform::filterAllColumns($row,$meta);
$row = DataTransform::sanitizeData($row,$meta);
return $row;
}
function sanitizeData($newRow,$meta,$t=null){
$newRow = DataTransform::sanitizeReferences($newRow,$meta);
$newRow = DataTransform::sanitizeOwnerFields($newRow,$meta,$t);
$newRow = DataTransform::sanitizeFields($newRow,$meta);
return $newRow;
}
function sanitizeForInsert($row,$meta){
global $adb;
$associatedToUser = false;
$parentTypeId = null;
if(strtolower($meta->getEntityName()) == "emails"){
if(isset($row['parent_id'])){
$components = vtws_getIdComponents($row['parent_id']);
$userObj = VtigerWebserviceObject::fromName($adb,'Users');
$parentTypeId = $components[0];
if($components[0] == $userObj->getEntityId()){
$associatedToUser = true;
}
}
}
// added to handle the setting reminder time
if(strtolower($meta->getEntityName()) == "events"){
if(isset($row['reminder_time'])&& $row['reminder_time']!= null && $row['reminder_time'] != 0){
$_REQUEST['set_reminder'] = "Yes";
$_REQUEST['mode'] = 'edit';
$reminder = $row['reminder_time'];
$seconds = (int)$reminder%60;
$minutes = (int)($reminder/60)%60;
$hours = (int)($reminder/(60*60))%24;
$days = (int)($reminder/(60*60*24));
//at vtiger there cant be 0 minutes reminder so we are setting to 1
if($minutes == 0){
$minutes = 1;
}
$_REQUEST['remmin'] = $minutes;
$_REQUEST['remhrs'] = $hours;
$_REQUEST['remdays'] = $days;
} else {
$_REQUEST['set_reminder'] = "No";
}
} elseif(strtolower($meta->getEntityName()) == "calendar") {
if(empty($row['sendnotification']) || strtolower($row['sendnotificaiton'])=='no'
|| $row['sendnotificaiton'] == '0' || $row['sendnotificaiton'] == 'false'
|| strtolower($row['sendnotificaiton']) == 'n') {
unset($row['sendnotification']);
}
}
$references = $meta->getReferenceFieldDetails();
foreach($references as $field=>$typeList){
if(strpos($row[$field],'x')!==false){
$row[$field] = vtws_getIdComponents($row[$field]);
$row[$field] = $row[$field][1];
}
}
$ownerFields = $meta->getOwnerFields();
foreach($ownerFields as $index=>$field){
if(isset($row[$field]) && $row[$field]!=null){
$ownerDetails = vtws_getIdComponents($row[$field]);
$row[$field] = $ownerDetails[1];
}
}
if(strtolower($meta->getEntityName()) == "emails"){
if(isset($row['parent_id'])){
if($associatedToUser === true){
$_REQUEST['module'] = 'Emails';
$row['parent_id'] = $row['parent_id']."@-1|";
$_REQUEST['parent_id'] = $row['parent_id'];
}else{
$referenceHandler = vtws_getModuleHandlerFromId($parentTypeId,
$meta->getUser());
$referenceMeta = $referenceHandler->getMeta();
$fieldId = getEmailFieldId($referenceMeta, $row['parent_id']);
$row['parent_id'] .= "@$fieldId|";
}
}
}
if($row["id"]){
unset($row["id"]);
}
if(isset($row[$meta->getObectIndexColumn()])){
unset($row[$meta->getObectIndexColumn()]);
}
$row = DataTransform::sanitizeDateFieldsForInsert($row,$meta);
$row = DataTransform::sanitizeCurrencyFieldsForInsert($row,$meta);
return $row;
}
function filterAllColumns($row,$meta){
$recordString = DataTransform::$recordString;
$allFields = $meta->getFieldColumnMapping();
$newRow = array();
foreach($allFields as $field=>$col){
$newRow[$field] = $row[$field];
}
if(isset($row[$recordString])){
$newRow[$recordString] = $row[$recordString];
}
return $newRow;
}
function sanitizeFields($row,$meta){
$default_charset = VTWS_PreserveGlobal::getGlobal('default_charset');
$recordString = DataTransform::$recordString;
$recordModuleString = DataTransform::$recordModuleString;
if(isset($row[$recordModuleString])){
unset($row[$recordModuleString]);
}
if(isset($row['id'])){
if(strpos($row['id'],'x')===false){
$row['id'] = vtws_getId($meta->getEntityId(),$row['id']);
}
}
if(isset($row[$recordString])){
$row['id'] = vtws_getId($meta->getEntityId(),$row[$recordString]);
unset($row[$recordString]);
}
if(!isset($row['id'])){
if($row[$meta->getObectIndexColumn()] ){
$row['id'] = vtws_getId($meta->getEntityId(),$row[$meta->getObectIndexColumn()]);
}else{
//TODO Handle this.
//echo 'error id noy set' ;
}
}else if(isset($row[$meta->getObectIndexColumn()]) && strcmp($meta->getObectIndexColumn(),"id")!==0){
unset($row[$meta->getObectIndexColumn()]);
}
foreach ($row as $field => $value) {
$row[$field] = html_entity_decode($value, ENT_QUOTES, $default_charset);
}
return $row;
}
function sanitizeReferences($row,$meta){
global $adb,$log;
$references = $meta->getReferenceFieldDetails();
foreach($references as $field=>$typeList){
if(strtolower($meta->getEntityName()) == "emails"){
if(isset($row['parent_id'])){
list($row['parent_id'], $fieldId) = explode('@',
$row['parent_id']);
}
}
if($row[$field]){
$found = false;
foreach ($typeList as $entity) {
$webserviceObject = VtigerWebserviceObject::fromName($adb,$entity);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$meta->getUser(),$adb,$log);
$entityMeta = $handler->getMeta();
if($entityMeta->exists($row[$field])){
$row[$field] = vtws_getId($webserviceObject->getEntityId(),$row[$field]);
$found = true;
break;
}
}
if($found !== true){
//This is needed as for query operation of the related record is deleted.
$row[$field] = null;
}
//0 is the default for most of the reference fields, so handle the case and return null instead as its the
//only valid value, which is not a reference Id.
}elseif(isset($row[$field]) && $row[$field]==0){
$row[$field] = null;
}
}
return $row;
}
function sanitizeOwnerFields($row,$meta,$t=null){
global $adb;
$ownerFields = $meta->getOwnerFields();
foreach($ownerFields as $index=>$field){
if(isset($row[$field]) && $row[$field]!=null){
$ownerType = vtws_getOwnerType($row[$field]);
$webserviceObject = VtigerWebserviceObject::fromName($adb,$ownerType);
$row[$field] = vtws_getId($webserviceObject->getEntityId(),$row[$field]);
}
}
return $row;
}
function sanitizeDateFieldsForInsert($row,$meta){
global $current_user;
$moduleFields = $meta->getModuleFields();
foreach($moduleFields as $fieldName=>$fieldObj){
if($fieldObj->getFieldDataType()=="date"){
if(!empty($row[$fieldName])){
$dateFieldObj = new DateTimeField($row[$fieldName]);
$row[$fieldName] = $dateFieldObj->getDisplayDate($current_user);
}
}
}
return $row;
}
function sanitizeCurrencyFieldsForInsert($row,$meta){
global $current_user;
$moduleFields = $meta->getModuleFields();
foreach($moduleFields as $fieldName=>$fieldObj){
if($fieldObj->getFieldDataType()=="currency"){
if(!empty($row[$fieldName])){
$row[$fieldName] = CurrencyField::convertToUserFormat($row[$fieldName],$current_user,true);
}
}
}
return $row;
}
}
?>

View File

@ -0,0 +1,49 @@
<?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.
*************************************************************************************/
function vtws_delete($id,$user){
global $log,$adb;
$webserviceObject = VtigerWebserviceObject::fromId($adb,$id);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$meta = $handler->getMeta();
$entityName = $meta->getObjectEntityName($id);
$types = vtws_listtypes(null, $user);
if(!in_array($entityName,$types['types'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied");
}
if($entityName !== $webserviceObject->getEntityName()){
throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect");
}
if(!$meta->hasPermission(EntityMeta::$DELETE,$id)){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to read given object is denied");
}
$idComponents = vtws_getIdComponents($id);
if(!$meta->exists($idComponents[1])){
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND,"Record you are trying to access is not found");
}
if($meta->hasDeleteAccess()!==true){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to delete is denied");
}
$entity = $handler->delete($id);
VTWS_PreserveGlobal::flush();
return $entity;
}
?>

View File

@ -0,0 +1,70 @@
<?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
*/
function vtws_deleteUser($id, $newOwnerId,$user){
global $log,$adb;
$webserviceObject = VtigerWebserviceObject::fromId($adb,$id);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$meta = $handler->getMeta();
$entityName = $meta->getObjectEntityName($id);
$types = vtws_listtypes($user);
if(!in_array($entityName,$types['types'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,
"Permission to perform the operation is denied, EntityName = ".$entityName);
}
if($entityName !== $webserviceObject->getEntityName()){
throw new WebServiceException(WebServiceErrorCode::$INVALIDID,
"Id specified is incorrect");
}
if(!$meta->hasPermission(EntityMeta::$DELETE,$id)){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,
"Permission to read given object is denied");
}
$idComponents = vtws_getIdComponents($id);
if(!$meta->exists($idComponents[1])){
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND,
"Record you are trying to access is not found, idComponent = ".$idComponents);
}
if($meta->hasWriteAccess()!==true){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,
"Permission to write is denied");
}
$newIdComponents = vtws_getIdComponents($newOwnerId);
if(empty($newIdComponents[1])) {
//force the default user to be the default admin user.
//added cause eazybusiness team is sending this value empty
$newIdComponents[1] = 1;
}
vtws_transferOwnership($idComponents[1], $newIdComponents[1]);
//delete from user vtiger_table;
$sql = "delete from vtiger_users where id=?";
vtws_runQueryAsTransaction($sql, array($idComponents[1]), $result);
VTWS_PreserveGlobal::flush();
return array("status"=>"successful");
}
?>

View File

@ -0,0 +1,33 @@
<?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.
*************************************************************************************/
function vtws_describe($elementType,$user){
global $log,$adb;
$webserviceObject = VtigerWebserviceObject::fromName($adb,$elementType);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$meta = $handler->getMeta();
$types = vtws_listtypes(null, $user);
if(!in_array($elementType,$types['types'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied");
}
$entity = $handler->describe($elementType);
VTWS_PreserveGlobal::flush();
return $entity;
}
?>

View File

@ -0,0 +1,258 @@
<?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 EntityMeta{
public static $RETRIEVE = "DetailView";
public static $CREATE = "Save";
public static $UPDATE = "EditView";
public static $DELETE = "Delete";
protected $webserviceObject;
protected $objectName;
protected $objectId;
protected $user;
protected $baseTable;
protected $tableList;
protected $tableIndexList;
protected $defaultTableList;
protected $idColumn;
protected $userAccessibleColumns;
protected $columnTableMapping;
protected $fieldColumnMapping;
protected $mandatoryFields;
protected $referenceFieldDetails;
protected $emailFields;
protected $ownerFields;
protected $moduleFields;
protected function EntityMeta($webserviceObject,$user){
$this->webserviceObject = $webserviceObject;
$this->objectName = $this->webserviceObject->getEntityName();
$this->objectId = $this->webserviceObject->getEntityId();
$this->user = $user;
}
public function getEmailFields(){
if($this->emailFields === null){
$this->emailFields = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
if(strcasecmp($webserviceField->getFieldType(),'e') === 0){
array_push($this->emailFields, $fieldName);
}
}
}
return $this->emailFields;
}
public function getFieldColumnMapping(){
if($this->fieldColumnMapping === null){
$this->fieldColumnMapping = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
$this->fieldColumnMapping[$fieldName] = $webserviceField->getColumnName();
}
$this->fieldColumnMapping['id'] = $this->idColumn;
}
return $this->fieldColumnMapping;
}
public function getMandatoryFields(){
if($this->mandatoryFields === null){
$this->mandatoryFields = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
if($webserviceField->isMandatory() === true){
array_push($this->mandatoryFields,$fieldName);
}
}
}
return $this->mandatoryFields;
}
public function getReferenceFieldDetails(){
if($this->referenceFieldDetails === null){
$this->referenceFieldDetails = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
if(strcasecmp($webserviceField->getFieldDataType(),'reference') === 0){
$this->referenceFieldDetails[$fieldName] = $webserviceField->getReferenceList();
}
}
}
return $this->referenceFieldDetails;
}
public function getOwnerFields(){
if($this->ownerFields === null){
$this->ownerFields = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
if(strcasecmp($webserviceField->getFieldDataType(),'owner') === 0){
array_push($this->ownerFields, $fieldName);
}
}
}
return $this->ownerFields;
}
public function getObectIndexColumn(){
return $this->idColumn;
}
public function getUserAccessibleColumns(){
if($this->userAccessibleColumns === null){
$this->userAccessibleColumns = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
array_push($this->userAccessibleColumns,$webserviceField->getColumnName());
}
array_push($this->userAccessibleColumns,$this->idColumn);
}
return $this->userAccessibleColumns;
}
public function getFieldByColumnName($column){
$fields = $this->getModuleFields();
foreach ($fields as $fieldName=>$webserviceField) {
if($column == $webserviceField->getColumnName()) {
return $webserviceField;
}
}
return null;
}
public function getColumnTableMapping(){
if($this->columnTableMapping === null){
$this->columnTableMapping = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
$this->columnTableMapping[$webserviceField->getColumnName()] = $webserviceField->getTableName();
}
$this->columnTableMapping[$this->idColumn] = $this->baseTable;
}
return $this->columnTableMapping;
}
function getUser(){
return $this->user;
}
function hasMandatoryFields($row){
$mandatoryFields = $this->getMandatoryFields();
$hasMandatory = true;
foreach($mandatoryFields as $ind=>$field){
// dont use empty API as '0'(zero) is a valid value.
if( !isset($row[$field]) || $row[$field] === "" || $row[$field] === null ){
throw new WebServiceException(WebServiceErrorCode::$MANDFIELDSMISSING,
"$field does not have a value");
}
}
return $hasMandatory;
}
public function isUpdateMandatoryFields($element){
if(!is_array($element)){
throw new WebServiceException(WebServiceErrorCode::$MANDFIELDSMISSING,
"Mandatory field does not have a value");
}
$mandatoryFields = $this->getMandatoryFields();
$updateFields = array_keys($element);
$hasMandatory = true;
$updateMandatoryFields = array_intersect($updateFields, $mandatoryFields);
if(!empty($updateMandatoryFields)){
foreach($updateMandatoryFields as $ind=>$field){
// dont use empty API as '0'(zero) is a valid value.
if( !isset($element[$field]) || $element[$field] === "" || $element[$field] === null ){
throw new WebServiceException(WebServiceErrorCode::$MANDFIELDSMISSING,
"$field does not have a value");
}
}
}
return $hasMandatory;
}
public function getModuleFields(){
return $this->moduleFields;
}
public function getFieldNameListByType($type) {
$type = strtolower($type);
$typeList = array();
$moduleFields = $this->getModuleFields();
foreach ($moduleFields as $fieldName=>$webserviceField) {
if(strcmp($webserviceField->getFieldDataType(),$type) === 0){
array_push($typeList, $fieldName);
}
}
return $typeList;
}
public function getFieldListByType($type) {
$type = strtolower($type);
$typeList = array();
$moduleFields = $this->getModuleFields();
foreach ($moduleFields as $fieldName=>$webserviceField) {
if(strcmp($webserviceField->getFieldDataType(),$type) === 0){
array_push($typeList, $webserviceField);
}
}
return $typeList;
}
public function getIdColumn(){
return $this->idColumn;
}
public function getEntityBaseTable() {
return $this->baseTable;
}
public function getEntityTableIndexList() {
return $this->tableIndexList;
}
public function getEntityDefaultTableList() {
return $this->defaultTableList;
}
public function getEntityTableList() {
return $this->tableList;
}
public function getEntityAccessControlQuery(){
$accessControlQuery = '';
return $accessControlQuery;
}
public function getEntityDeletedQuery(){
if($this->getEntityName() == 'Leads') {
return "vtiger_crmentity.deleted=0 and vtiger_leaddetails.converted=0";
}
if($this->getEntityName() != "Users"){
return "vtiger_crmentity.deleted=0";
}
// not sure whether inactive users should be considered deleted or not.
return "vtiger_users.status='Active'";
}
abstract function hasPermission($operation,$webserviceId);
abstract function hasAssignPrivilege($ownerWebserviceId);
abstract function hasDeleteAccess();
abstract function hasAccess();
abstract function hasReadAccess();
abstract function hasWriteAccess();
abstract function getEntityName();
abstract function getEntityId();
abstract function exists($recordId);
abstract function getObjectEntityName($webserviceId);
abstract public function getNameFields();
abstract public function getName($webserviceId);
abstract public function isModuleEntity();
}
?>

View File

@ -0,0 +1,26 @@
<?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.
*************************************************************************************/
function vtws_extendSession(){
global $adb,$API_VERSION,$application_unique_key;
if(isset($_SESSION["authenticated_user_id"]) && $_SESSION["app_unique_key"] == $application_unique_key){
$userId = $_SESSION["authenticated_user_id"];
$sessionManager = new SessionManager();
$sessionManager->set("authenticatedUserId", $userId);
$crmObject = VtigerWebserviceObject::fromName($adb,"Users");
$userId = vtws_getId($crmObject->getEntityId(),$userId);
$vtigerVersion = vtws_getVtigerVersion();
$resp = array("sessionName"=>$sessionManager->getSessionId(),"userId"=>$userId,"version"=>$API_VERSION,"vtigerVersion"=>$vtigerVersion);
return $resp;
}else{
throw new WebServiceException(WebServiceErrorCode::$AUTHFAILURE,"Authencation Failed");
}
}
?>

View File

@ -0,0 +1,282 @@
<?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 'include/Webservices/Utils.php';
require_once 'include/Webservices/ModuleTypes.php';
require_once 'include/utils/CommonUtils.php';
function vtws_sync($mtime,$elementType,$syncType,$user){
global $adb, $recordString,$modifiedTimeString;
$numRecordsLimit = 100;
$ignoreModules = array("Users");
$typed = true;
$dformat = "Y-m-d H:i:s";
$datetime = date($dformat, $mtime);
$setypeArray = array();
$setypeData = array();
$setypeHandler = array();
$setypeNoAccessArray = array();
$output = array();
$output["updated"] = array();
$output["deleted"] = array();
$applicationSync = false;
if(is_object($syncType) && ($syncType instanceof Users)){
$user = $syncType;
} else if($syncType == 'application'){
$applicationSync = true;
}
if($applicationSync && !is_admin($user)){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Only admin users can perform application sync");
}
$ownerIds = array($user->id);
if(!isset($elementType) || $elementType=='' || $elementType==null){
$typed=false;
}
$adb->startTransaction();
$accessableModules = array();
$entityModules = array();
$modulesDetails = vtws_listtypes(null,$user);
$moduleTypes = $modulesDetails['types'];
$modulesInformation = $modulesDetails["information"];
foreach($modulesInformation as $moduleName=>$entityInformation){
if($entityInformation["isEntity"])
$entityModules[] = $moduleName;
}
if(!$typed){
$accessableModules = $entityModules;
}
else{
if(!in_array($elementType,$entityModules))
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied");
$accessableModules[] = $elementType;
}
$accessableModules = array_diff($accessableModules,$ignoreModules);
if(count($accessableModules)<=0)
{
$output['lastModifiedTime'] = $mtime;
$output['more'] = false;
return $output;
}
if($typed){
$handler = vtws_getModuleHandlerFromName($elementType, $user);
$moduleMeta = $handler->getMeta();
$entityDefaultBaseTables = $moduleMeta->getEntityDefaultTableList();
//since there will be only one base table for all entities
$baseCRMTable = $entityDefaultBaseTables[0];
if($elementType=="Calendar" || $elementType=="Events" ){
$baseCRMTable = getSyncQueryBaseTable($elementType);
}
}
else
$baseCRMTable = " vtiger_crmentity ";
//modifiedtime - next token
$q = "SELECT modifiedtime FROM $baseCRMTable WHERE modifiedtime>? and setype IN(".generateQuestionMarks($accessableModules).") ";
$params = array($datetime);
foreach($accessableModules as $entityModule){
if($entityModule == "Events")
$entityModule = "Calendar";
$params[] = $entityModule;
}
if(!$applicationSync){
$q .= ' and smownerid IN('.generateQuestionMarks($ownerIds).')';
$params = array_merge($params,$ownerIds);
}
$q .=" order by modifiedtime limit $numRecordsLimit";
$result = $adb->pquery($q,$params);
$modTime = array();
for($i=0;$i<$adb->num_rows($result);$i++){
$modTime[] = $adb->query_result($result,$i,'modifiedtime');
}
if(!empty($modTime)){
$maxModifiedTime = max($modTime);
}
if(!$maxModifiedTime){
$maxModifiedTime = $datetime;
}
foreach($accessableModules as $elementType){
$handler = vtws_getModuleHandlerFromName($elementType, $user);
$moduleMeta = $handler->getMeta();
$deletedQueryCondition = $moduleMeta->getEntityDeletedQuery();
preg_match_all("/(?:\s+\w+[ \t\n\r]+)?([^=]+)\s*=([^\s]+|'[^']+')/",$deletedQueryCondition,$deletedFieldDetails);
$fieldNameDetails = $deletedFieldDetails[1];
$deleteFieldValues = $deletedFieldDetails[2];
$deleteColumnNames = array();
foreach($fieldNameDetails as $tableName_fieldName){
$fieldComp = explode(".",$tableName_fieldName);
$deleteColumnNames[$tableName_fieldName] = $fieldComp[1];
}
$params = array($moduleMeta->getTabName(),$datetime,$maxModifiedTime);
$queryGenerator = new QueryGenerator($elementType, $user);
$fields = array();
$moduleFeilds = $moduleMeta->getModuleFields();
$moduleFeildNames = array_keys($moduleFeilds);
$moduleFeildNames[]='id';
$queryGenerator->setFields($moduleFeildNames);
$selectClause = "SELECT ".$queryGenerator->getSelectClauseColumnSQL();
// adding the fieldnames that are present in the delete condition to the select clause
// since not all fields present in delete condition will be present in the fieldnames of the module
foreach($deleteColumnNames as $table_fieldName=>$columnName){
if(!in_array($columnName,$moduleFeildNames)){
$selectClause .=", ".$table_fieldName;
}
}
if($elementType=="Emails")
$fromClause = vtws_getEmailFromClause();
else
$fromClause = $queryGenerator->getFromClause();
$fromClause .= " INNER JOIN (select modifiedtime, crmid,deleted,setype FROM $baseCRMTable WHERE setype=? and modifiedtime >? and modifiedtime<=?";
if(!$applicationSync){
$fromClause.= 'and smownerid IN('.generateQuestionMarks($ownerIds).')';
$params = array_merge($params,$ownerIds);
}
$fromClause.= ' ) vtiger_ws_sync ON (vtiger_crmentity.crmid = vtiger_ws_sync.crmid)';
$q = $selectClause." ".$fromClause;
$result = $adb->pquery($q, $params);
$recordDetails = array();
$deleteRecordDetails = array();
while($arre = $adb->fetchByAssoc($result)){
$key = $arre[$moduleMeta->getIdColumn()];
if(vtws_isRecordDeleted($arre,$deleteColumnNames,$deleteFieldValues)){
if(!$moduleMeta->hasAccess()){
continue;
}
$output["deleted"][] = vtws_getId($moduleMeta->getEntityId(), $key);
}
else{
if(!$moduleMeta->hasAccess() ||!$moduleMeta->hasPermission(EntityMeta::$RETRIEVE,$key)){
continue;
}
try{
$output["updated"][] = DataTransform::sanitizeDataWithColumn($arre,$moduleMeta);;
}catch(WebServiceException $e){
//ignore records the user doesn't have access to.
continue;
}catch(Exception $e){
throw new WebServiceException(WebServiceErrorCode::$INTERNALERROR,"Unknown Error while processing request");
}
}
}
}
$q = "SELECT crmid FROM $baseCRMTable WHERE modifiedtime>? and setype IN(".generateQuestionMarks($accessableModules).")";
$params = array($maxModifiedTime);
foreach($accessableModules as $entityModule){
if($entityModule == "Events")
$entityModule = "Calendar";
$params[] = $entityModule;
}
if(!$applicationSync){
$q.='and smownerid IN('.generateQuestionMarks($ownerIds).')';
$params = array_merge($params,$ownerIds);
}
$result = $adb->pquery($q,$params);
if($adb->num_rows($result)>0){
$output['more'] = true;
}
else{
$output['more'] = false;
}
if(!$maxModifiedTime){
$modifiedtime = $mtime;
}else{
$modifiedtime = vtws_getSeconds($maxModifiedTime);
}
if(is_string($modifiedtime)){
$modifiedtime = intval($modifiedtime);
}
$output['lastModifiedTime'] = $modifiedtime;
$error = $adb->hasFailedTransaction();
$adb->completeTransaction();
if($error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
VTWS_PreserveGlobal::flush();
return $output;
}
function vtws_getSeconds($mtimeString){
//TODO handle timezone and change time to gmt.
return strtotime($mtimeString);
}
function vtws_isRecordDeleted($recordDetails,$deleteColumnDetails,$deletedValues){
$deletedRecord = false;
$i=0;
foreach($deleteColumnDetails as $tableName_fieldName=>$columnName){
if($recordDetails[$columnName]!=$deletedValues[$i++]){
$deletedRecord = true;
break;
}
}
return $deletedRecord;
}
function vtws_getEmailFromClause(){
$q = "FROM vtiger_activity
INNER JOIN vtiger_crmentity ON vtiger_activity.activityid = vtiger_crmentity.crmid
LEFT JOIN vtiger_users ON vtiger_crmentity.smownerid = vtiger_users.id
LEFT JOIN vtiger_groups ON vtiger_crmentity.smownerid = vtiger_groups.groupid
LEFT JOIN vtiger_seattachmentsrel ON vtiger_activity.activityid = vtiger_seattachmentsrel.crmid
LEFT JOIN vtiger_attachments ON vtiger_seattachmentsrel.attachmentsid = vtiger_attachments.attachmentsid
LEFT JOIN vtiger_email_track ON vtiger_activity.activityid = vtiger_email_track.mailid
INNER JOIN vtiger_emaildetails ON vtiger_activity.activityid = vtiger_emaildetails.emailid
LEFT JOIN vtiger_users vtiger_users2 ON vtiger_emaildetails.idlists = vtiger_users2.id
LEFT JOIN vtiger_groups vtiger_groups2 ON vtiger_emaildetails.idlists = vtiger_groups2.groupid";
return $q;
}
function getSyncQueryBaseTable($elementType){
if($elementType!="Calendar" && $elementType!="Events"){
return "vtiger_crmentity";
}
else{
$activityCondition = getCalendarTypeCondition($elementType);
$query = "vtiger_crmentity INNER JOIN vtiger_activity ON (vtiger_crmentity.crmid = vtiger_activity.activityid and $activityCondition)";
return $query;
}
}
function getCalendarTypeCondition($elementType){
if($elementType == "Events")
$activityCondition = "vtiger_activity.activitytype !='Task' and vtiger_activity.activitytype !='Emails'";
else
$activityCondition = "vtiger_activity.activitytype ='Task'";
return $activityCondition;
}
?>

View File

@ -0,0 +1,63 @@
<?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.
*************************************************************************************/
function vtws_login($username,$pwd){
$user = new Users();
$userId = $user->retrieve_user_id($username);
$token = vtws_getActiveToken($userId);
if($token == null){
throw new WebServiceException(WebServiceErrorCode::$INVALIDTOKEN,"Specified token is invalid or expired");
}
$accessKey = vtws_getUserAccessKey($userId);
if($accessKey == null){
throw new WebServiceException(WebServiceErrorCode::$ACCESSKEYUNDEFINED,"Access key for the user is undefined");
}
$accessCrypt = md5($token.$accessKey);
if(strcmp($accessCrypt,$pwd)!==0){
throw new WebServiceException(WebServiceErrorCode::$INVALIDUSERPWD,"Invalid username or password");
}
$user = $user->retrieveCurrentUserInfoFromFile($userId);
if($user->status != 'Inactive'){
return $user;
}
throw new WebServiceException(WebServiceErrorCode::$AUTHREQUIRED,'Given user is inactive');
}
function vtws_getActiveToken($userId){
global $adb;
$sql = "select * from vtiger_ws_userauthtoken where userid=? and expiretime >= ?";
$result = $adb->pquery($sql,array($userId,time()));
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
return $adb->query_result($result,0,"token");
}
}
return null;
}
function vtws_getUserAccessKey($userId){
global $adb;
$sql = "select * from vtiger_users where id=?";
$result = $adb->pquery($sql,array($userId));
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
return $adb->query_result($result,0,"accesskey");
}
}
return null;
}
?>

View File

@ -0,0 +1,24 @@
<?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.
*************************************************************************************/
function vtws_logout($sessionId,$user){
$sessionManager = new SessionManager();
$sid = $sessionManager->startSession($sessionId);
if(!isset($sessionId) || !$sessionManager->isValid()){
return $sessionManager->getError();
}
$sessionManager->destroy();
// $sessionManager->setExpire(1);
return array("message"=>"successfull");
}
?>

View File

@ -0,0 +1,136 @@
<?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.
*************************************************************************************/
function vtws_listtypes($fieldTypeList, $user){
// Bulk Save Mode: For re-using information
static $webserviceEntities = false;
// END
static $types = array();
if(!empty($fieldTypeList)) {
$fieldTypeList = array_map(strtolower, $fieldTypeList);
sort($fieldTypeList);
$fieldTypeString = implode(',', $fieldTypeList);
} else {
$fieldTypeString = 'all';
}
if(!empty($types[$user->id][$fieldTypeString])) {
return $types[$user->id][$fieldTypeString];
}
try{
global $log;
/**
* @var PearDatabase
*/
$db = PearDatabase::getInstance();
vtws_preserveGlobal('current_user',$user);
//get All the modules the current user is permitted to Access.
$allModuleNames = getPermittedModuleNames();
if(array_search('Calendar',$allModuleNames) !== false){
array_push($allModuleNames,'Events');
}
if(!empty($fieldTypeList)) {
$sql = "SELECT distinct(vtiger_field.tabid) as tabid FROM vtiger_field LEFT JOIN vtiger_ws_fieldtype ON ".
"vtiger_field.uitype=vtiger_ws_fieldtype.uitype
INNER JOIN vtiger_profile2field ON vtiger_field.fieldid = vtiger_profile2field.fieldid
INNER JOIN vtiger_def_org_field ON vtiger_def_org_field.fieldid = vtiger_field.fieldid
INNER JOIN vtiger_role2profile ON vtiger_profile2field.profileid = vtiger_role2profile.profileid
INNER JOIN vtiger_user2role ON vtiger_user2role.roleid = vtiger_role2profile.roleid
where vtiger_profile2field.visible=0 and vtiger_def_org_field.visible = 0
and vtiger_field.presence in (0,2)
and vtiger_user2role.userid=? and fieldtype in (".
generateQuestionMarks($fieldTypeList).')';
$params = array();
$params[] = $user->id;
foreach($fieldTypeList as $fieldType)
$params[] = $fieldType;
$result = $db->pquery($sql, $params);
$it = new SqlResultIterator($db, $result);
$moduleList = array();
foreach ($it as $row) {
$moduleList[] = getTabModuleName($row->tabid);
}
$allModuleNames = array_intersect($moduleList, $allModuleNames);
$params = $fieldTypeList;
$sql = "select name from vtiger_ws_entity inner join vtiger_ws_entity_tables on ".
"vtiger_ws_entity.id=vtiger_ws_entity_tables.webservice_entity_id inner join ".
"vtiger_ws_entity_fieldtype on vtiger_ws_entity_fieldtype.table_name=".
"vtiger_ws_entity_tables.table_name where fieldtype=(".
generateQuestionMarks($fieldTypeList).')';
$result = $db->pquery($sql, $params);
$it = new SqlResultIterator($db, $result);
$entityList = array();
foreach ($it as $row) {
$entityList[] = $row->name;
}
}
//get All the CRM entity names.
if($webserviceEntities === false || !CRMEntity::isBulkSaveMode()) {
// Bulk Save Mode: For re-using information
$webserviceEntities = vtws_getWebserviceEntities();
}
$accessibleModules = array_values(array_intersect($webserviceEntities['module'],$allModuleNames));
$entities = $webserviceEntities['entity'];
$accessibleEntities = array();
if(empty($fieldTypeList)) {
foreach($entities as $entity){
$webserviceObject = VtigerWebserviceObject::fromName($db,$entity);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$db,$log);
$meta = $handler->getMeta();
if($meta->hasAccess()===true){
array_push($accessibleEntities,$entity);
}
}
}
}catch(WebServiceException $exception){
throw $exception;
}catch(Exception $exception){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
"An Database error occured while performing the operation");
}
$default_language = VTWS_PreserveGlobal::getGlobal('default_language');
$current_language = vtws_preserveGlobal('current_language',$default_language);
$appStrings = return_application_language($current_language);
$appListString = return_app_list_strings_language($current_language);
vtws_preserveGlobal('app_strings',$appStrings);
vtws_preserveGlobal('app_list_strings',$appListString);
$informationArray = array();
foreach ($accessibleModules as $module) {
$vtigerModule = ($module == 'Events')? 'Calendar':$module;
$informationArray[$module] = array('isEntity'=>true,'label'=>getTranslatedString($module,$vtigerModule),
'singular'=>getTranslatedString('SINGLE_'.$module,$vtigerModule));
}
foreach ($accessibleEntities as $entity) {
$label = (isset($appStrings[$entity]))? $appStrings[$entity]:$entity;
$singular = (isset($appStrings['SINGLE_'.$entity]))? $appStrings['SINGLE_'.$entity]:$entity;
$informationArray[$entity] = array('isEntity'=>false,'label'=>$label,
'singular'=>$singular);
}
VTWS_PreserveGlobal::flush();
$types[$user->id][$fieldTypeString] = array("types"=>array_merge($accessibleModules,$accessibleEntities),
'information'=>$informationArray);
return $types[$user->id][$fieldTypeString];
}
?>

View File

@ -0,0 +1,181 @@
<?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.
*************************************************************************************/
function setBuiltIn($json){
$json->useBuiltinEncoderDecoder = true;
}
class OperationManager{
private $format;
private $formatsData=array(
"json"=>array(
"includePath"=>"include/Zend/Json.php",
"class"=>"Zend_Json",
"encodeMethod"=>"encode",
"decodeMethod"=>"decode",
"postCreate"=>"setBuiltIn"
)
);
private $operationMeta = null;
private $formatObjects ;
private $inParamProcess ;
private $sessionManager;
private $pearDB;
private $operationName;
private $type;
private $handlerPath;
private $handlerMethod;
private $preLogin;
private $operationId;
private $operationParams;
function OperationManager($adb,$operationName,$format, $sessionManager){
$this->format = strtolower($format);
$this->sessionManager = $sessionManager;
$this->formatObjects = array();
foreach($this->formatsData as $frmt=>$frmtData){
require_once($frmtData["includePath"]);
$instance = new $frmtData["class"]();
$this->formatObjects[$frmt]["encode"] = array(&$instance,$frmtData["encodeMethod"]);
$this->formatObjects[$frmt]["decode"] = array(&$instance,$frmtData["decodeMethod"]);
if($frmtData["postCreate"]){
call_user_func($frmtData["postCreate"],$instance);
}
}
$this->pearDB = $adb;
$this->operationName = $operationName;
$this->inParamProcess = array();
$this->inParamProcess["encoded"] = &$this->formatObjects[$this->format]["decode"];
$this->fillOperationDetails($operationName);
}
function isPreLoginOperation(){
return $this->preLogin == 1;
}
private function fillOperationDetails($operationName){
$sql = "select * from vtiger_ws_operation where name=?";
$result = $this->pearDB->pquery($sql,array($operationName));
if($result){
$rowCount = $this->pearDB->num_rows($result);
if($rowCount > 0){
$row = $this->pearDB->query_result_rowdata($result,0);
$this->type = $row['type'];
$this->handlerMethod = $row['handler_method'];
$this->handlerPath = $row['handler_path'];
$this->preLogin = $row['prelogin'];
$this->operationName = $row['name'];
$this->operationId = $row['operationid'];
$this->fillOperationParameters();
return;
}
}
throw new WebServiceException(WebServiceErrorCode::$UNKNOWNOPERATION,"Unknown operation requested");
}
private function fillOperationParameters(){
$sql = "select * from vtiger_ws_operation_parameters where operationid=? order by sequence";
$result = $this->pearDB->pquery($sql,array($this->operationId));
$this->operationParams = array();
if($result){
$rowCount = $this->pearDB->num_rows($result);
if($rowCount > 0){
for ($i=0;$i<$rowCount;++$i){
$row = $this->pearDB->query_result_rowdata($result,$i);
array_push($this->operationParams,array($row['name']=>$row['type']));
}
}
}
}
public function getOperationInput(){
$type = strtolower($this->type);
switch($type){
case 'get': $input = &$_GET;
return $input;
case 'post': $input = &$_POST;
return $input;
default: $input = &$_REQUEST;
return $input;
}
}
function sanitizeOperation($input){
return $this->sanitizeInputForType($input);
}
function sanitizeInputForType($input){
$sanitizedInput = array();
foreach($this->operationParams as $ind=>$columnDetails){
foreach ($columnDetails as $columnName => $type) {
$sanitizedInput[$columnName] = $this->handleType($type,vtws_getParameter($input,$columnName));;
}
}
return $sanitizedInput;
}
function handleType($type,$value){
$result;
$value = stripslashes($value);
$type = strtolower($type);
if($this->inParamProcess[$type]){
$result = call_user_func($this->inParamProcess[$type],$value);
}else{
$result = $value;
}
return $result;
}
function runOperation($params,$user){
global $API_VERSION;
try{
$operation = strtolower($this->operationName);
if(!$this->preLogin){
$params[] = $user;
return call_user_func_array($this->handlerMethod,$params);
}else{
$userDetails = call_user_func_array($this->handlerMethod,$params);
if(is_array($userDetails)){
return $userDetails;
}else{
$this->sessionManager->set("authenticatedUserId", $userDetails->id);
global $adb;
$webserviceObject = VtigerWebserviceObject::fromName($adb,"Users");
$userId = vtws_getId($webserviceObject->getEntityId(),$userDetails->id);
$vtigerVersion = vtws_getVtigerVersion();
$resp = array("sessionName"=>$this->sessionManager->getSessionId(),"userId"=>$userId,"version"=>$API_VERSION,"vtigerVersion"=>$vtigerVersion);
return $resp;
}
}
}catch(WebServiceException $e){
throw $e;
}catch(Exception $e){
throw new WebServiceException(WebServiceErrorCode::$INTERNALERROR,"Unknown Error while processing request");
}
}
function encode($param){
return call_user_func($this->formatObjects[$this->format]["encode"],$param);
}
function getOperationIncludes(){
$includes = array();
array_push($includes,$this->handlerPath);
return $includes;
}
}
?>

View File

@ -0,0 +1,54 @@
<?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 VTWS_PreserveGlobal{
private static $globalData = array();
static function preserveGlobal($name,$value){
//$name store the name of the global.
global $$name;
if(!is_array(VTWS_PreserveGlobal::$globalData[$name])){
VTWS_PreserveGlobal::$globalData[$name] = array();
VTWS_PreserveGlobal::$globalData[$name][] = $$name;
}
$$name = $value;
return $$name;
}
static function restore($name){
//$name store the name of the global.
global $$name;
if(is_array(VTWS_PreserveGlobal::$globalData[$name]) && count(VTWS_PreserveGlobal::$globalData[$name]) > 0){
$$name = array_pop(VTWS_PreserveGlobal::$globalData[$name]);
}
$$name;
}
static function getGlobal($name){
global $$name;
return VTWS_PreserveGlobal::preserveGlobal($name,$$name);
}
static function flush(){
foreach (VTWS_PreserveGlobal::$globalData as $name => $detail) {
//$name store the name of the global.
global $$name;
if(is_array(VTWS_PreserveGlobal::$globalData[$name]) && count(VTWS_PreserveGlobal::$globalData[$name]) > 0) {
$$name = array_pop(VTWS_PreserveGlobal::$globalData[$name]);
}
}
}
}
?>

View File

@ -0,0 +1,69 @@
<?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("include/Webservices/QueryParser.php");
function vtws_query($q,$user){
static $vtws_query_cache = array();
global $log,$adb;
// Cache the instance for re-use
$moduleRegex = "/[fF][rR][Oo][Mm]\s+([^\s;]+)/";
$moduleName = '';
if(preg_match($moduleRegex, $q, $m)) $moduleName = trim($m[1]);
if(!isset($vtws_create_cache[$moduleName]['webserviceobject'])) {
$webserviceObject = VtigerWebserviceObject::fromQuery($adb,$q);
$vtws_query_cache[$moduleName]['webserviceobject'] = $webserviceObject;
} else {
$webserviceObject = $vtws_query_cache[$moduleName]['webserviceobject'];
}
// END
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
// Cache the instance for re-use
if(!isset($vtws_query_cache[$moduleName]['handler'])) {
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$vtws_query_cache[$moduleName]['handler'] = $handler;
} else {
$handler = $vtws_query_cache[$moduleName]['handler'];
}
// END
// Cache the instance for re-use
if(!isset($vtws_query_cache[$moduleName]['meta'])) {
$meta = $handler->getMeta();
$vtws_query_cache[$moduleName]['meta'] = $meta;
} else {
$meta = $vtws_query_cache[$moduleName]['meta'];
}
// END
$types = vtws_listtypes(null, $user);
if(!in_array($webserviceObject->getEntityName(),$types['types'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied");
}
if(!$meta->hasReadAccess()){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to read is denied");
}
$result = $handler->query($q);
VTWS_PreserveGlobal::flush();
return $result;
}
?>

View File

@ -0,0 +1,64 @@
<?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("include/Webservices/VTQL_Lexer.php");
require_once("include/Webservices/VTQL_Parser.php");
class Parser{
private $query = "";
private $out;
private $meta;
private $hasError ;
private $error ;
private $user;
function Parser($user, $q){
$this->query = $q;
$this->out = array();
$this->hasError = false;
$this->user = $user;
}
function parse(){
$lex = new VTQL_Lexer($this->query);
$parser = new VTQL_Parser($this->user, $lex,$this->out);
while ($lex->yylex()) {
$parser->doParse($lex->token, $lex->value);
}
$parser->doParse(0, 0);
if($parser->isSuccess()){
$this->hasError = false;
$this->query = $parser->getQuery();
$this->meta = $parser->getObjectMetaData();
}else{
$this->hasError = true;
$this->error = $parser->getErrorMsg();
}
return $this->hasError;
}
function getSql(){
return $this->query;
}
function getObjectMetaData(){
return $this->meta;
}
function getError(){
return $this->error;
}
}
?>

View File

@ -0,0 +1,88 @@
<?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.
*
*********************************************************************************/
/**
* Description of RelatedModuleMeta
* TODO to add and extend a way to track many-many and many-one relationships.
* @author MAK
*/
class RelatedModuleMeta {
private $module;
private $relatedModule;
private $CAMPAIGNCONTACTREL = 1;
private $PRODUCTQUOTESREL = 2;
private $PRODUCTINVOICEREL = 3;
private $PRODUCTPURCHASEORDERREL = 4;
private function __construct($module, $relatedModule) {
$this->module = $module;
$this->relatedModule = $relatedModule;
}
/**
*
* @param <type> $module
* @param <type> $relatedModule
* @return RelatedModuleMeta
*/
public static function getInstance($module, $relatedModule) {
return new RelatedModuleMeta($module, $relatedModule);
}
public function getRelationMeta() {
$campaignContactRel = array('Campaigns','Contacts');
$productInvoiceRel = array('Products','Invoice');
$productQuotesRel = array('Products','Quotes');
$productPurchaseOrder = array('Products','PurchaseOrder');
if(in_array($this->module, $campaignContactRel) && in_array($this->relatedModule,
$campaignContactRel)) {
return $this->getRelationMetaInfo($this->CAMPAIGNCONTACTREL);
}
if(in_array($this->module, $productInvoiceRel) && in_array($this->relatedModule,
$productInvoiceRel)) {
return $this->getRelationMetaInfo($this->PRODUCTINVOICEREL);
}
if(in_array($this->module, $productQuotesRel) && in_array($this->relatedModule,
$productQuotesRel)) {
return $this->getRelationMetaInfo($this->PRODUCTQUOTESREL);
}
if(in_array($this->module, $productPurchaseOrder) && in_array($this->relatedModule,
$productPurchaseOrder)) {
return $this->getRelationMetaInfo($this->PRODUCTPURCHASEORDERREL);
}
}
private function getRelationMetaInfo($relationId) {
switch($relationId) {
case $this->CAMPAIGNCONTACTREL: return array(
'relationTable' => 'vtiger_campaigncontrel',
'Campaigns' => 'campaignid',
'Contacts' => 'contactid'
);
case $this->PRODUCTINVOICEREL: return array(
'relationTable' => 'vtiger_inventoryproductrel',
'Products' => 'productid',
'Invoice' => 'id'
);
case $this->PRODUCTQUOTESREL: return array(
'relationTable' => 'vtiger_inventoryproductrel',
'Products' => 'productid',
'Quotes' => 'id'
);
case $this->PRODUCTPURCHASEORDERREL: return array(
'relationTable' => 'vtiger_inventoryproductrel',
'Products' => 'productid',
'PurchaseOrder' => 'id'
);
}
}
}
?>

View File

@ -0,0 +1,49 @@
<?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.
*************************************************************************************/
function vtws_retrieve($id, $user){
global $log,$adb;
$webserviceObject = VtigerWebserviceObject::fromId($adb,$id);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$meta = $handler->getMeta();
$entityName = $meta->getObjectEntityName($id);
$types = vtws_listtypes(null, $user);
if(!in_array($entityName,$types['types'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied");
}
if($meta->hasReadAccess()!==true){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to write is denied");
}
if($entityName !== $webserviceObject->getEntityName()){
throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect");
}
if(!$meta->hasPermission(EntityMeta::$RETRIEVE,$id)){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to read given object is denied");
}
$idComponents = vtws_getIdComponents($id);
if(!$meta->exists($idComponents[1])){
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND,"Record you are trying to access is not found");
}
$entity = $handler->retrieve($id);
VTWS_PreserveGlobal::flush();
return $entity;
}
?>

View File

@ -0,0 +1,87 @@
<?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.
*************************************************************************************/
function vtws_revise($element,$user){
global $log,$adb;
$idList = vtws_getIdComponents($element['id']);
$webserviceObject = VtigerWebserviceObject::fromId($adb,$idList[0]);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$meta = $handler->getMeta();
$entityName = $meta->getObjectEntityName($element['id']);
$types = vtws_listtypes(null, $user);
if(!in_array($entityName,$types['types'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied");
}
if($entityName !== $webserviceObject->getEntityName()){
throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect");
}
if(!$meta->hasPermission(EntityMeta::$UPDATE,$element['id'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to read given object is denied");
}
if(!$meta->exists($idList[1])){
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND,"Record you are trying to access is not found");
}
if($meta->hasWriteAccess()!==true){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to write is denied");
}
$referenceFields = $meta->getReferenceFieldDetails();
foreach($referenceFields as $fieldName=>$details){
if(isset($element[$fieldName]) && strlen($element[$fieldName]) > 0){
$ids = vtws_getIdComponents($element[$fieldName]);
$elemTypeId = $ids[0];
$elemId = $ids[1];
$referenceObject = VtigerWebserviceObject::fromId($adb,$elemTypeId);
if (!in_array($referenceObject->getEntityName(),$details)){
throw new WebServiceException(WebServiceErrorCode::$REFERENCEINVALID,
"Invalid reference specified for $fieldName");
}
if ($referenceObject->getEntityName() == 'Users') {
if(!$meta->hasAssignPrivilege($element[$fieldName])) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Cannot assign record to the given user");
}
}
if (!in_array($referenceObject->getEntityName(), $types['types']) && $referenceObject->getEntityName() != 'Users') {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,
"Permission to access reference type is denied ".$referenceObject->getEntityName());
}
}
}
//check if the element has mandtory fields filled
$meta->isUpdateMandatoryFields($element);
$ownerFields = $meta->getOwnerFields();
if(is_array($ownerFields) && sizeof($ownerFields) >0){
foreach($ownerFields as $ownerField){
if(isset($element[$ownerField]) && $element[$ownerField]!==null &&
!$meta->hasAssignPrivilege($element[$ownerField])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Cannot assign record to the given user");
}
}
}
$entity = $handler->revise($element);
VTWS_PreserveGlobal::flush();
return $entity;
}
?>

View File

@ -0,0 +1,132 @@
<?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("include/HTTP_Session/Session.php");
// Later may we can move this to config file.
global $maxWebServiceSessionLifeSpan, $maxWebServiceSessionIdleTime;
$maxWebServiceSessionLifeSpan = 86400; //Max life span of a session is a day.
$maxWebServiceSessionIdleTime = 1800; //Max life span session should be kept alive after the last transaction.
// Till Here.
class SessionManager{
private $maxLife ;
private $idleLife ;
//Note: the url lookup part of http_session will have String null or this be used as id instead of ignoring it.
//private $sessionName = "sessionName";
private $sessionVar = "__SessionExists";
private $error ;
function SessionManager(){
global $maxWebServiceSessionLifeSpan, $maxWebServiceSessionIdleTime;
$now = time();
$this->maxLife = $now + $maxWebServiceSessionLifeSpan;
$this->idleLife = $now + $maxWebServiceSessionIdleTime;
HTTP_Session::useCookies(false); //disable cookie usage. may this could be moved out constructor?
// only first invocation of following method, which is setExpire
//have an effect and any further invocation will be have no effect.
HTTP_Session::setExpire($this->maxLife);
// this method replaces the new with old time if second params is true
//otherwise it subtracts the time from previous time
HTTP_Session::setIdle($this->idleLife, true);
}
function isValid(){
$valid = true;
// expired
if (HTTP_Session::isExpired()) {
$valid = false;
HTTP_Session::destroy();
throw new WebServiceException(WebServiceErrorCode::$SESSLIFEOVER,"Session has life span over please login again");
}
// idled
if (HTTP_Session::isIdle()) {
$valid = false;
HTTP_Session::destroy();
throw new WebServiceException(WebServiceErrorCode::$SESSIONIDLE,"Session has been invalidated to due lack activity");
}
//echo "<br>is new: ", HTTP_Session::isNew();
//invalid sessionId provided.
//echo "<br>get: ",$this->get($this->sessionVar);
if(!$this->get($this->sessionVar) && !HTTP_Session::isNew()){
$valid = false;
HTTP_Session::destroy();
throw new WebServiceException(WebServiceErrorCode::$SESSIONIDINVALID,"Session Identifier provided is Invalid");
}
return $valid;
}
function startSession($sid = null,$adoptSession=false){
// if($sid){
// HTTP_Session::id($sid);
// }
if(!$sid || strlen($sid) ===0){
$sid = null;
}
//session name is used for guessing the session id by http_session so pass null.
HTTP_Session::start(null, $sid);
$newSID = HTTP_Session::id();
if(!$sid || $adoptSession==true){
$this->set($this->sessionVar,"true");
}else{
if(!$this->get($this->sessionVar)){
HTTP_Session::destroy();
throw new WebServiceException(WebServiceErrorCode::$SESSIONIDINVALID,"Session Identifier provided is Invalid");
$newSID = null;
}
}
if(!$this->isValid()){
$newSID = null;
}
$sid = $newSID;
return $sid;
}
function getSessionId(){
return HTTP_Session::id();
}
function set($var_name, $var_value){
//TODO test setRef and getRef combination
//echo "<br>setting name: ",$var_name," :value: ",$var_value;
HTTP_Session::set($var_name, $var_value);
}
function get($name){
//echo "<br> getting for: ",$name," :value: ",HTTP_Session::get($name);
return HTTP_Session::get($name);
}
FUNCTION getError(){
return $this->error;
}
function destroy(){
HTTP_Session::destroy();
}
}
?>

View File

@ -0,0 +1,25 @@
<?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 State{
var $success ;
var $result ;
var $error;
function State(){
$this->success = false;
$this->result = array();
$this->error = array();
}
}
?>

View File

@ -0,0 +1,88 @@
<?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.
*************************************************************************************/
function vtws_update($element,$user){
global $log,$adb;
$idList = vtws_getIdComponents($element['id']);
$webserviceObject = VtigerWebserviceObject::fromId($adb,$idList[0]);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$meta = $handler->getMeta();
$entityName = $meta->getObjectEntityName($element['id']);
$types = vtws_listtypes(null, $user);
if(!in_array($entityName,$types['types'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied");
}
if($entityName !== $webserviceObject->getEntityName()){
throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect");
}
if(!$meta->hasPermission(EntityMeta::$UPDATE,$element['id'])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to read given object is denied");
}
if(!$meta->exists($idList[1])){
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND,"Record you are trying to access is not found");
}
if($meta->hasWriteAccess()!==true){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to write is denied");
}
$referenceFields = $meta->getReferenceFieldDetails();
foreach($referenceFields as $fieldName=>$details){
if(isset($element[$fieldName]) && strlen($element[$fieldName]) > 0){
$ids = vtws_getIdComponents($element[$fieldName]);
$elemTypeId = $ids[0];
$elemId = $ids[1];
$referenceObject = VtigerWebserviceObject::fromId($adb,$elemTypeId);
if (!in_array($referenceObject->getEntityName(),$details)){
throw new WebServiceException(WebServiceErrorCode::$REFERENCEINVALID,
"Invalid reference specified for $fieldName");
}
if ($referenceObject->getEntityName() == 'Users') {
if(!$meta->hasAssignPrivilege($element[$fieldName])) {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Cannot assign record to the given user");
}
}
if (!in_array($referenceObject->getEntityName(), $types['types']) && $referenceObject->getEntityName() != 'Users') {
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,
"Permission to access reference type is denied ".$referenceObject->getEntityName());
}
}else if($element[$fieldName] !== NULL){
unset($element[$fieldName]);
}
}
$meta->hasMandatoryFields($element);
$ownerFields = $meta->getOwnerFields();
if(is_array($ownerFields) && sizeof($ownerFields) >0){
foreach($ownerFields as $ownerField){
if(isset($element[$ownerField]) && $element[$ownerField]!==null &&
!$meta->hasAssignPrivilege($element[$ownerField])){
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Cannot assign record to the given user");
}
}
}
$entity = $handler->update($element);
VTWS_PreserveGlobal::flush();
return $entity;
}
?>

View File

@ -0,0 +1,919 @@
<?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('include/database/PearDatabase.php');
require_once("modules/Users/Users.php");
require_once 'include/Webservices/WebserviceField.php';
require_once 'include/Webservices/EntityMeta.php';
require_once 'include/Webservices/VtigerWebserviceObject.php';
require_once("include/Webservices/VtigerCRMObject.php");
require_once("include/Webservices/VtigerCRMObjectMeta.php");
require_once("include/Webservices/DataTransform.php");
require_once("include/Webservices/WebServiceError.php");
require_once 'include/utils/utils.php';
require_once 'include/utils/UserInfoUtil.php';
require_once 'include/Webservices/ModuleTypes.php';
require_once 'include/utils/VtlibUtils.php';
require_once 'include/Webservices/WebserviceEntityOperation.php';
require_once 'include/Webservices/PreserveGlobal.php';
/* Function to return all the users in the groups that this user is part of.
* @param $id - id of the user
* returns Array:UserIds userid of all the users in the groups that this user is part of.
*/
function vtws_getUsersInTheSameGroup($id){
require_once('include/utils/GetGroupUsers.php');
require_once('include/utils/GetUserGroups.php');
$groupUsers = new GetGroupUsers();
$userGroups = new GetUserGroups();
$allUsers = Array();
$userGroups->getAllUserGroups($id);
$groups = $userGroups->user_groups;
foreach ($groups as $group) {
$groupUsers->getAllUsersInGroup($group);
$usersInGroup = $groupUsers->group_users;
foreach ($usersInGroup as $user) {
if($user != $id){
$allUsers[$user] = getUserFullName($user);
}
}
}
return $allUsers;
}
function vtws_generateRandomAccessKey($length=10){
$source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$accesskey = "";
$maxIndex = strlen($source);
for($i=0;$i<$length;++$i){
$accesskey = $accesskey.substr($source,rand(null,$maxIndex),1);
}
return $accesskey;
}
/**
* get current vtiger version from the database.
*/
function vtws_getVtigerVersion(){
global $adb;
$query = 'select * from vtiger_version';
$result = $adb->pquery($query, array());
$version = '';
while($row = $adb->fetch_array($result))
{
$version = $row['current_version'];
}
return $version;
}
function vtws_getUserAccessibleGroups($moduleId, $user){
global $adb;
require('user_privileges/user_privileges_'.$user->id.'.php');
require('user_privileges/sharing_privileges_'.$user->id.'.php');
$tabName = getTabname($moduleId);
if($is_admin==false && $profileGlobalPermission[2] == 1 &&
($defaultOrgSharingPermission[$moduleId] == 3 or $defaultOrgSharingPermission[$moduleId] == 0)){
$result=get_current_user_access_groups($tabName);
}else{
$result = get_group_options();
}
$groups = array();
if($result != null && $result != '' && is_object($result)){
$rowCount = $adb->num_rows($result);
for ($i = 0; $i < $rowCount; $i++) {
$nameArray = $adb->query_result_rowdata($result,$i);
$groupId=$nameArray["groupid"];
$groupName=$nameArray["groupname"];
$groups[] = array('id'=>$groupId,'name'=>$groupName);
}
}
return $groups;
}
function vtws_getWebserviceGroupFromGroups($groups){
global $adb;
$webserviceObject = VtigerWebserviceObject::fromName($adb,'Groups');
foreach($groups as $index=>$group){
$groups[$index]['id'] = vtws_getId($webserviceObject->getEntityId(),$group['id']);
}
return $groups;
}
function vtws_getUserWebservicesGroups($tabId,$user){
$groups = vtws_getUserAccessibleGroups($tabId,$user);
return vtws_getWebserviceGroupFromGroups($groups);
}
function vtws_getIdComponents($elementid){
return explode("x",$elementid);
}
function vtws_getId($objId, $elemId){
return $objId."x".$elemId;
}
function getEmailFieldId($meta, $entityId){
global $adb;
//no email field accessible in the module. since its only association pick up the field any way.
$query="SELECT fieldid,fieldlabel,columnname FROM vtiger_field WHERE tabid=?
and uitype=13 and presence in (0,2)";
$result = $adb->pquery($query, array($meta->getTabId()));
//pick up the first field.
$fieldId = $adb->query_result($result,0,'fieldid');
return $fieldId;
}
function vtws_getParameter($parameterArray, $paramName,$default=null){
if (!get_magic_quotes_gpc()) {
if(is_array($parameterArray[$paramName])) {
$param = array_map('addslashes', $parameterArray[$paramName]);
} else {
$param = addslashes($parameterArray[$paramName]);
}
} else {
$param = $parameterArray[$paramName];
}
if(!$param){
$param = $default;
}
return $param;
}
function vtws_getEntityNameFields($moduleName){
global $adb;
$query = "select fieldname,tablename,entityidfield from vtiger_entityname where modulename = ?";
$result = $adb->pquery($query, array($moduleName));
$rowCount = $adb->num_rows($result);
$nameFields = array();
if($rowCount > 0){
$fieldsname = $adb->query_result($result,0,'fieldname');
if(!(strpos($fieldsname,',') === false)){
$nameFields = explode(',',$fieldsname);
}else{
array_push($nameFields,$fieldsname);
}
}
return $nameFields;
}
/** function to get the module List to which are crm entities.
* @return Array modules list as array
*/
function vtws_getModuleNameList(){
global $adb;
$sql = "select name from vtiger_tab where isentitytype=1 and name not in ('Rss','Webmails',".
"'Recyclebin','Events') order by tabsequence";
$res = $adb->pquery($sql, array());
$mod_array = Array();
while($row = $adb->fetchByAssoc($res)){
array_push($mod_array,$row['name']);
}
return $mod_array;
}
function vtws_getWebserviceEntities(){
global $adb;
$sql = "select name,id,ismodule from vtiger_ws_entity";
$res = $adb->pquery($sql, array());
$moduleArray = Array();
$entityArray = Array();
while($row = $adb->fetchByAssoc($res)){
if($row['ismodule'] == '1'){
array_push($moduleArray,$row['name']);
}else{
array_push($entityArray,$row['name']);
}
}
return array('module'=>$moduleArray,'entity'=>$entityArray);
}
/**
*
* @param VtigerWebserviceObject $webserviceObject
* @return CRMEntity
*/
function vtws_getModuleInstance($webserviceObject){
$moduleName = $webserviceObject->getEntityName();
return CRMEntity::getInstance($moduleName);
}
function vtws_isRecordOwnerUser($ownerId){
global $adb;
$result = $adb->pquery("select first_name from vtiger_users where id = ?",array($ownerId));
$rowCount = $adb->num_rows($result);
$ownedByUser = ($rowCount > 0);
return $ownedByUser;
}
function vtws_isRecordOwnerGroup($ownerId){
global $adb;
$result = $adb->pquery("select groupname from vtiger_groups where groupid = ?",array($ownerId));
$rowCount = $adb->num_rows($result);
$ownedByGroup = ($rowCount > 0);
return $ownedByGroup;
}
function vtws_getOwnerType($ownerId){
if(vtws_isRecordOwnerGroup($ownerId) == true){
return 'Groups';
}
if(vtws_isRecordOwnerUser($ownerId) == true){
return 'Users';
}
throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Invalid owner of the record");
}
function vtws_runQueryAsTransaction($query,$params,&$result){
global $adb;
$adb->startTransaction();
$result = $adb->pquery($query,$params);
$error = $adb->hasFailedTransaction();
$adb->completeTransaction();
return !$error;
}
function vtws_getCalendarEntityType($id){
global $adb;
$sql = "select activitytype from vtiger_activity where activityid=?";
$result = $adb->pquery($sql,array($id));
$seType = 'Calendar';
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
$activityType = $adb->query_result($result,0,"activitytype");
if($activityType !== "Task"){
$seType = "Events";
}
}
}
return $seType;
}
/***
* Get the webservice reference Id given the entity's id and it's type name
*/
function vtws_getWebserviceEntityId($entityName, $id){
global $adb;
$webserviceObject = VtigerWebserviceObject::fromName($adb,$entityName);
return $webserviceObject->getEntityId().'x'.$id;
}
function vtws_addDefaultModuleTypeEntity($moduleName){
global $adb;
$isModule = 1;
$moduleHandler = array('file'=>'include/Webservices/VtigerModuleOperation.php',
'class'=>'VtigerModuleOperation');
return vtws_addModuleTypeWebserviceEntity($moduleName,$moduleHandler['file'],$moduleHandler['class'],$isModule);
}
function vtws_addModuleTypeWebserviceEntity($moduleName,$filePath,$className){
global $adb;
$checkres = $adb->pquery('SELECT id FROM vtiger_ws_entity WHERE name=? AND handler_path=? AND handler_class=?',
array($moduleName, $filePath, $className));
if($checkres && $adb->num_rows($checkres) == 0) {
$isModule=1;
$entityId = $adb->getUniqueID("vtiger_ws_entity");
$adb->pquery('insert into vtiger_ws_entity(id,name,handler_path,handler_class,ismodule) values (?,?,?,?,?)',
array($entityId,$moduleName,$filePath,$className,$isModule));
}
}
function vtws_deleteWebserviceEntity($moduleName) {
global $adb;
$adb->pquery('DELETE FROM vtiger_ws_entity WHERE name=?',array($moduleName));
}
function vtws_addDefaultActorTypeEntity($actorName,$actorNameDetails,$withName = true){
$actorHandler = array('file'=>'include/Webservices/VtigerActorOperation.php',
'class'=>'VtigerActorOperation');
if($withName == true){
vtws_addActorTypeWebserviceEntityWithName($actorName,$actorHandler['file'],$actorHandler['class'],
$actorNameDetails);
}else{
vtws_addActorTypeWebserviceEntityWithoutName($actorName,$actorHandler['file'],$actorHandler['class'],
$actorNameDetails);
}
}
function vtws_addActorTypeWebserviceEntityWithName($moduleName,$filePath,$className,$actorNameDetails){
global $adb;
$isModule=0;
$entityId = $adb->getUniqueID("vtiger_ws_entity");
$adb->pquery('insert into vtiger_ws_entity(id,name,handler_path,handler_class,ismodule) values (?,?,?,?,?)',
array($entityId,$moduleName,$filePath,$className,$isModule));
vtws_addActorTypeName($entityId,$actorNameDetails['fieldNames'],$actorNameDetails['indexField'],
$actorNameDetails['tableName']);
}
function vtws_addActorTypeWebserviceEntityWithoutName($moduleName,$filePath,$className,$actorNameDetails){
global $adb;
$isModule=0;
$entityId = $adb->getUniqueID("vtiger_ws_entity");
$adb->pquery('insert into vtiger_ws_entity(id,name,handler_path,handler_class,ismodule) values (?,?,?,?,?)',
array($entityId,$moduleName,$filePath,$className,$isModule));
}
function vtws_addActorTypeName($entityId,$fieldNames,$indexColumn,$tableName){
global $adb;
$adb->pquery('insert into vtiger_ws_entity_name(entity_id,name_fields,index_field,table_name) values (?,?,?,?)',
array($entityId,$fieldNames,$indexColumn,$tableName));
}
function vtws_getName($id,$user){
global $log,$adb;
$webserviceObject = VtigerWebserviceObject::fromId($adb,$id);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
$meta = $handler->getMeta();
return $meta->getName($id);
}
function vtws_preserveGlobal($name,$value){
return VTWS_PreserveGlobal::preserveGlobal($name,$value);
}
/**
* Takes the details of a webservices and exposes it over http.
* @param $name name of the webservice to be added with namespace.
* @param $handlerFilePath file to be include which provides the handler method for the given webservice.
* @param $handlerMethodName name of the function to the called when this webservice is invoked.
* @param $requestType type of request that this operation should be, if in doubt give it as GET,
* general rule of thumb is that, if the operation is adding/updating data on server then it must be POST
* otherwise it should be GET.
* @param $preLogin 0 if the operation need the user to authorised to access the webservice and
* 1 if the operation is called before login operation hence the there will be no user authorisation happening
* for the operation.
* @return Integer operationId of successful or null upon failure.
*/
function vtws_addWebserviceOperation($name,$handlerFilePath,$handlerMethodName,$requestType,$preLogin = 0){
global $adb;
$createOperationQuery = "insert into vtiger_ws_operation(operationid,name,handler_path,handler_method,type,prelogin)
values (?,?,?,?,?,?);";
if(strtolower($requestType) != 'get' && strtolower($requestType) != 'post'){
return null;
}
$requestType = strtoupper($requestType);
if(empty($preLogin)){
$preLogin = 0;
}else{
$preLogin = 1;
}
$operationId = $adb->getUniqueID("vtiger_ws_operation");
$result = $adb->pquery($createOperationQuery,array($operationId,$name,$handlerFilePath,$handlerMethodName,
$requestType,$preLogin));
if($result !== false){
return $operationId;
}
return null;
}
/**
* Add a parameter to a webservice.
* @param $operationId Id of the operation for which a webservice needs to be added.
* @param $paramName name of the parameter used to pickup value from request(POST/GET) object.
* @param $paramType type of the parameter, it can either 'string','datetime' or 'encoded'
* encoded type is used for input which will be encoded in JSON or XML(NOT SUPPORTED).
* @param $sequence sequence of the parameter in the definition in the handler method.
* @return Boolean true if the parameter was added successfully, false otherwise
*/
function vtws_addWebserviceOperationParam($operationId,$paramName,$paramType,$sequence){
global $adb;
$supportedTypes = array('string','encoded','datetime','double','boolean');
if(!is_numeric($sequence)){
$sequence = 1;
}if($sequence <=1){
$sequence = 1;
}
if(!in_array(strtolower($paramType),$supportedTypes)){
return false;
}
$createOperationParamsQuery = "insert into vtiger_ws_operation_parameters(operationid,name,type,sequence)
values (?,?,?,?);";
$result = $adb->pquery($createOperationParamsQuery,array($operationId,$paramName,$paramType,$sequence));
return ($result !== false);
}
/**
*
* @global PearDatabase $adb
* @global <type> $log
* @param <type> $name
* @param <type> $user
* @return WebserviceEntityOperation
*/
function vtws_getModuleHandlerFromName($name,$user){
global $adb, $log;
$webserviceObject = VtigerWebserviceObject::fromName($adb,$name);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
return $handler;
}
function vtws_getModuleHandlerFromId($id,$user){
global $adb, $log;
$webserviceObject = VtigerWebserviceObject::fromId($adb,$id);
$handlerPath = $webserviceObject->getHandlerPath();
$handlerClass = $webserviceObject->getHandlerClass();
require_once $handlerPath;
$handler = new $handlerClass($webserviceObject,$user,$adb,$log);
return $handler;
}
function vtws_CreateCompanyLogoFile($fieldname) {
global $root_directory;
$uploaddir = $root_directory ."/test/logo/";
$allowedFileTypes = array("jpeg", "png", "jpg", "pjpeg" ,"x-png");
$binFile = $_FILES[$fieldname]['name'];
$fileType = $_FILES[$fieldname]['type'];
$fileSize = $_FILES[$fieldname]['size'];
$fileTypeArray = explode("/",$fileType);
$fileTypeValue = strtolower($fileTypeArray[1]);
if($fileTypeValue == '') {
$fileTypeValue = substr($binFile,strrpos($binFile, '.')+1);
}
if($fileSize != 0) {
if(in_array($fileTypeValue, $allowedFileTypes)) {
move_uploaded_file($_FILES[$fieldname]["tmp_name"],
$uploaddir.$_FILES[$fieldname]["name"]);
return $binFile;
}
throw new WebServiceException(WebServiceErrorCode::$INVALIDTOKEN,
"$fieldname wrong file type given for upload");
}
throw new WebServiceException(WebServiceErrorCode::$INVALIDTOKEN,
"$fieldname file upload failed");
}
function vtws_getActorEntityName ($name, $idList) {
$db = PearDatabase::getInstance();
if (!is_array($idList) && count($idList) == 0) {
return array();
}
$entity = VtigerWebserviceObject::fromName($db, $name);
return vtws_getActorEntityNameById($entity->getEntityId(), $idList);
}
function vtws_getActorEntityNameById ($entityId, $idList) {
$db = PearDatabase::getInstance();
if (!is_array($idList) && count($idList) == 0) {
return array();
}
$nameList = array();
$webserviceObject = VtigerWebserviceObject::fromId($db, $entityId);
$query = "select * from vtiger_ws_entity_name where entity_id = ?";
$result = $db->pquery($query, array($entityId));
if (is_object($result)) {
$rowCount = $db->num_rows($result);
if ($rowCount > 0) {
$nameFields = $db->query_result($result,0,'name_fields');
$tableName = $db->query_result($result,0,'table_name');
$indexField = $db->query_result($result,0,'index_field');
if (!(strpos($nameFields,',') === false)) {
$fieldList = explode(',',$nameFields);
$nameFields = "concat(";
$nameFields = $nameFields.implode(",' ',",$fieldList);
$nameFields = $nameFields.")";
}
$query1 = "select $nameFields as entityname, $indexField from $tableName where ".
"$indexField in (".generateQuestionMarks($idList).")";
$params1 = array($idList);
$result = $db->pquery($query1, $params1);
if (is_object($result)) {
$rowCount = $db->num_rows($result);
for ($i = 0; $i < $rowCount; $i++) {
$id = $db->query_result($result,$i, $indexField);
$nameList[$id] = $db->query_result($result,$i,'entityname');
}
return $nameList;
}
}
}
return array();
}
function vtws_isRoleBasedPicklist($name) {
$db = PearDatabase::getInstance();
$sql = "select picklistid from vtiger_picklist where name = ?";
$result = $db->pquery($sql, array($name));
return ($db->num_rows($result) > 0);
}
function vtws_getConvertLeadFieldMapping(){
global $adb;
$sql = "select * from vtiger_convertleadmapping";
$result = $adb->pquery($sql,array());
if($result === false){
return null;
}
$mapping = array();
$rowCount = $adb->num_rows($result);
for($i=0;$i<$rowCount;++$i){
$row = $adb->query_result_rowdata($result,$i);
$mapping[$row['leadfid']] = array('Accounts'=>$row['accountfid'],
'Potentials'=>$row['potentialfid'],'Contacts'=>$row['contactfid']);
}
return $mapping;
}
/** Function used to get the lead related Notes and Attachments with other entities Account, Contact and Potential
* @param integer $id - leadid
* @param integer $relatedId - related entity id (accountid / contactid)
*/
function vtws_getRelatedNotesAttachments($id,$relatedId) {
global $adb,$log;
$sql = "select * from vtiger_senotesrel where crmid=?";
$result = $adb->pquery($sql, array($id));
if($result === false){
return false;
}
$rowCount = $adb->num_rows($result);
$sql="insert into vtiger_senotesrel(crmid,notesid) values (?,?)";
for($i=0; $i<$rowCount;++$i ) {
$noteId=$adb->query_result($result,$i,"notesid");
$resultNew = $adb->pquery($sql, array($relatedId, $noteId));
if($resultNew === false){
return false;
}
}
$sql = "select * from vtiger_seattachmentsrel where crmid=?";
$result = $adb->pquery($sql, array($id));
if($result === false){
return false;
}
$rowCount = $adb->num_rows($result);
$sql = "insert into vtiger_seattachmentsrel(crmid,attachmentsid) values (?,?)";
for($i=0;$i<$rowCount;++$i) {
$attachmentId=$adb->query_result($result,$i,"attachmentsid");
$resultNew = $adb->pquery($sql, array($relatedId, $attachmentId));
if($resultNew === false){
return false;
}
}
return true;
}
/** Function used to save the lead related products with other entities Account, Contact and Potential
* $leadid - leadid
* $relatedid - related entity id (accountid/contactid/potentialid)
* $setype - related module(Accounts/Contacts/Potentials)
*/
function vtws_saveLeadRelatedProducts($leadId, $relatedId, $setype) {
global $adb;
$result = $adb->pquery("select * from vtiger_seproductsrel where crmid=?", array($leadId));
if($result === false){
return false;
}
$rowCount = $adb->num_rows($result);
for($i = 0; $i < $rowCount; ++$i) {
$productId = $adb->query_result($result,$i,'productid');
$resultNew = $adb->pquery("insert into vtiger_seproductsrel values(?,?,?)", array($relatedId, $productId, $setype));
if($resultNew === false){
return false;
}
}
return true;
}
/** Function used to save the lead related services with other entities Account, Contact and Potential
* $leadid - leadid
* $relatedid - related entity id (accountid/contactid/potentialid)
* $setype - related module(Accounts/Contacts/Potentials)
*/
function vtws_saveLeadRelations($leadId, $relatedId, $setype) {
global $adb;
$result = $adb->pquery("select * from vtiger_crmentityrel where crmid=?", array($leadId));
if($result === false){
return false;
}
$rowCount = $adb->num_rows($result);
for($i = 0; $i < $rowCount; ++$i) {
$recordId = $adb->query_result($result,$i,'relcrmid');
$recordModule = $adb->query_result($result,$i,'relmodule');
$adb->pquery("insert into vtiger_crmentityrel values(?,?,?,?)",
array($relatedId, $setype, $recordId, $recordModule));
if($resultNew === false){
return false;
}
}
$result = $adb->pquery("select * from vtiger_crmentityrel where relcrmid=?", array($leadId));
if($result === false){
return false;
}
$rowCount = $adb->num_rows($result);
for($i = 0; $i < $rowCount; ++$i) {
$recordId = $adb->query_result($result,$i,'crmid');
$recordModule = $adb->query_result($result,$i,'module');
$adb->pquery("insert into vtiger_crmentityrel values(?,?,?,?)",
array($relatedId, $setype, $recordId, $recordModule));
if($resultNew === false){
return false;
}
}
return true;
}
function vtws_getFieldfromFieldId($fieldId, $fieldObjectList){
foreach ($fieldObjectList as $field) {
if($fieldId == $field->getFieldId()){
return $field;
}
}
return null;
}
/** Function used to get the lead related activities with other entities Account and Contact
* @param integer $leadId - lead entity id
* @param integer $accountId - related account id
* @param integer $contactId - related contact id
* @param integer $relatedId - related entity id to which the records need to be transferred
*/
function vtws_getRelatedActivities($leadId,$accountId,$contactId,$relatedId) {
if(empty($leadId) || empty($relatedId) || (empty($accountId) && empty($contactId))){
throw new WebServiceException(WebServiceErrorCode::$LEAD_RELATED_UPDATE_FAILED,
"Failed to move related Activities/Emails");
}
global $adb;
$sql = "select * from vtiger_seactivityrel where crmid=?";
$result = $adb->pquery($sql, array($leadId));
if($result === false){
return false;
}
$rowCount = $adb->num_rows($result);
for($i=0;$i<$rowCount;++$i) {
$activityId=$adb->query_result($result,$i,"activityid");
$sql ="select setype from vtiger_crmentity where crmid=?";
$resultNew = $adb->pquery($sql, array($activityId));
if($resultNew === false){
return false;
}
$type=$adb->query_result($resultNew,0,"setype");
$sql="delete from vtiger_seactivityrel where crmid=?";
$resultNew = $adb->pquery($sql, array($leadId));
if($resultNew === false){
return false;
}
if($type != "Emails") {
if(!empty($accountId)){
$sql = "insert into vtiger_seactivityrel(crmid,activityid) values (?,?)";
$resultNew = $adb->pquery($sql, array($accountId, $activityId));
if($resultNew === false){
return false;
}
}
if(!empty($contactId)){
$sql="insert into vtiger_cntactivityrel(contactid,activityid) values (?,?)";
$resultNew = $adb->pquery($sql, array($contactId, $activityId));
if($resultNew === false){
return false;
}
}
} else {
$sql = "insert into vtiger_seactivityrel(crmid,activityid) values (?,?)";
$resultNew = $adb->pquery($sql, array($relatedId, $activityId));
if($resultNew === false){
return false;
}
}
}
return true;
}
/**
* Function used to save the lead related Campaigns with Contact
* @param $leadid - leadid
* @param $relatedid - related entity id (contactid/accountid)
* @param $setype - related module(Accounts/Contacts)
* @return Boolean true on success, false otherwise.
*/
function vtws_saveLeadRelatedCampaigns($leadId, $relatedId, $seType) {
global $adb;
$result = $adb->pquery("select * from vtiger_campaignleadrel where leadid=?", array($leadId));
if($result === false){
return false;
}
$rowCount = $adb->num_rows($result);
for($i = 0; $i < $rowCount; ++$i) {
$campaignId = $adb->query_result($result,$i,'campaignid');
if($seType == 'Accounts') {
$resultNew = $adb->pquery("insert into vtiger_campaignaccountrel (campaignid, accountid) values(?,?)",
array($campaignId, $relatedId));
} elseif ($seType == 'Contacts') {
$resultNew = $adb->pquery("insert into vtiger_campaigncontrel (campaignid, contactid) values(?,?)",
array($campaignId, $relatedId));
}
if($resultNew === false){
return false;
}
}
return true;
}
/**
* Function used to transfer all the lead related records to given Entity(Contact/Account) record
* @param $leadid - leadid
* @param $relatedid - related entity id (contactid/accountid)
* @param $setype - related module(Accounts/Contacts)
*/
function vtws_transferLeadRelatedRecords($leadId, $relatedId, $seType) {
if(empty($leadId) || empty($relatedId) || empty($seType)){
throw new WebServiceException(WebServiceErrorCode::$LEAD_RELATED_UPDATE_FAILED,
"Failed to move related Records");
}
$status = vtws_getRelatedNotesAttachments($leadId, $relatedId);
if($status === false){
throw new WebServiceException(WebServiceErrorCode::$LEAD_RELATED_UPDATE_FAILED,
"Failed to move related Documents to the ".$seType);
}
//Retrieve the lead related products and relate them with this new account
$status = vtws_saveLeadRelatedProducts($leadId, $relatedId, $seType);
if($status === false){
throw new WebServiceException(WebServiceErrorCode::$LEAD_RELATED_UPDATE_FAILED,
"Failed to move related Products to the ".$seType);
}
$status = vtws_saveLeadRelations($leadId, $relatedId, $seType);
if($status === false){
throw new WebServiceException(WebServiceErrorCode::$LEAD_RELATED_UPDATE_FAILED,
"Failed to move Records to the ".$seType);
}
$status = vtws_saveLeadRelatedCampaigns($leadId, $relatedId, $seType);
if($status === false){
throw new WebServiceException(WebServiceErrorCode::$LEAD_RELATED_UPDATE_FAILED,
"Failed to move Records to the ".$seType);
}
vtws_transferComments($leadId, $relatedId);
}
function vtws_transferComments($sourceRecordId, $destinationRecordId) {
if(vtlib_isModuleActive('ModComments')) {
CRMEntity::getInstance('ModComments'); ModComments::transferRecords($sourceRecordId, $destinationRecordId);
}
}
function vtws_transferOwnership($ownerId, $newOwnerId, $delete=true) {
$db = PearDatabase::getInstance();
//Updating the smcreatorid,smownerid, modifiedby in vtiger_crmentity
$sql = "update vtiger_crmentity set smcreatorid=? where smcreatorid=?";
$db->pquery($sql, array($newOwnerId, $ownerId));
$sql = "update vtiger_crmentity set smownerid=? where smownerid=?";
$db->pquery($sql, array($newOwnerId, $ownerId));
$sql = "update vtiger_crmentity set modifiedby=? where modifiedby=?";
$db->pquery($sql, array($newOwnerId, $ownerId));
//deleting from vtiger_tracker
if ($delete) {
$sql = "delete from vtiger_tracker where user_id=?";
$db->pquery($sql, array($ownerId));
}
//updating created by in vtiger_lar
$sql = "update vtiger_lar set createdby=? where createdby=?";
$db->pquery($sql, array($newOwnerId, $ownerId));
//updating the vtiger_import_maps
$sql ="update vtiger_import_maps set assigned_user_id=? where assigned_user_id=?";
$db->pquery($sql, array($newOwnerId, $ownerId));
//update assigned_user_id in vtiger_files
$sql ="update vtiger_files set assigned_user_id=? where assigned_user_id=?";
$db->pquery($sql, array($newOwnerId, $ownerId));
if(Vtiger_Utils::CheckTable('vtiger_customerportal_prefs')) {
$query = 'UPDATE vtiger_customerportal_prefs SET prefvalue = ? WHERE prefkey = ? AND prefvalue = ?';
$params = array($newOwnerId, 'defaultassignee', $ownerId);
$db->pquery($query, $params);
$query = 'UPDATE vtiger_customerportal_prefs SET prefvalue = ? WHERE prefkey = ? AND prefvalue = ?';
$params = array($newOwnerId, 'userid', $ownerId);
$db->pquery($query, $params);
}
//delete from vtiger_homestuff
if ($delete) {
$sql = "delete from vtiger_homestuff where userid=?";
$db->pquery($sql, array($ownerId));
}
//delete from vtiger_users to group vtiger_table
if ($delete) {
$sql = "delete from vtiger_user2role where userid=?";
$db->pquery($sql, array($ownerId));
}
//delete from vtiger_users to vtiger_role vtiger_table
if ($delete) {
$sql = "delete from vtiger_users2group where userid=?";
$db->pquery($sql, array($ownerId));
}
$sql = "select tabid,fieldname,tablename,columnname from vtiger_field left join ".
"vtiger_fieldmodulerel on vtiger_field.fieldid=vtiger_fieldmodulerel.fieldid where uitype ".
"in (52,53,77,101) or (uitype=10 and relmodule='Users')";
$result = $db->pquery($sql, array());
$it = new SqlResultIterator($db, $result);
$columnList = array();
foreach ($it as $row) {
$column = $row->tablename.'.'.$row->columnname;
if(!in_array($column, $columnList)) {
$columnList[] = $column;
$sql = "update $row->tablename set $row->columnname=? where $row->columnname=?";
$db->pquery($sql, array($newOwnerId, $ownerId));
}
}
}
function vtws_getWebserviceTranslatedStringForLanguage($label, $currentLanguage) {
static $translations = array();
$currentLanguage = vtws_getWebserviceCurrentLanguage();
if(empty($translations[$currentLanguage])) {
include 'include/Webservices/language/'.$currentLanguage.'.lang.php';
$translations[$currentLanguage] = $webservice_strings;
}
if(isset($translations[$currentLanguage][$label])) {
return $translations[$currentLanguage][$label];
}
return null;
}
function vtws_getWebserviceTranslatedString($label) {
$currentLanguage = vtws_getWebserviceCurrentLanguage();
$translation = vtws_getWebserviceTranslatedStringForLanguage($label, $currentLanguage);
if(!empty($translation)) {
return $translation;
}
//current language doesn't have translation, return translation in default language
//if default language is english then LBL_ will not shown to the user.
$defaultLanguage = vtws_getWebserviceDefaultLanguage();
$translation = vtws_getWebserviceTranslatedStringForLanguage($label, $defaultLanguage);
if(!empty($translation)) {
return $translation;
}
//if default language is not en_us then do the translation in en_us to eliminate the LBL_ bit
//of label.
if('en_us' != $defaultLanguage) {
$translation = vtws_getWebserviceTranslatedStringForLanguage($label, 'en_us');
if(!empty($translation)) {
return $translation;
}
}
return $label;
}
function vtws_getWebserviceCurrentLanguage() {
global $default_language, $current_language;
if(empty($current_language)) {
return $default_language;
}
return $current_language;
}
function vtws_getWebserviceDefaultLanguage() {
global $default_language;
return $default_language;
}
?>

View File

@ -0,0 +1,316 @@
<?php
global $where_col,$orderby,$in_started,$count;
$where_col = false;
$orderby = false;
$in_started = false;
$count = false;
function incrementN($lexer, $count){
$i = 0;
for(;$i<$count;$i++){
incState($lexer);
}
}
function incState($lexer){
$lexer->current_state++;
if($lexer->current_state === sizeof($lexer->mandatory_states)){
$lexer->mandatory = false;
}
}
function handleselect($lexer, $val){
if($lexer->mandatory){
if(strcasecmp($val, $lexer->mandatory_states[$lexer->current_state])===0){
incState($lexer);
return VTQL_Parser::SELECT;
}
}
}
function handlecolumn_list($lexer, $val){
global $count;
if($lexer->mandatory){
if(!(strcasecmp($val, $lexer->mandatory_states[2])===0)){
if(strcmp($val, "*")===0){
if(!$count){
incrementN($lexer, 1);
}
return VTQL_Parser::ASTERISK;
}else if((strcmp($val, "(")===0)){
return VTQL_Parser::PARENOPEN;
}else if(strcmp($val, ")")===0){
return VTQL_Parser::PARENCLOSE;
}else if((strcasecmp($val, "count")===0)){
$count = true;
return VTQL_Parser::COUNT;
}else if(strcmp($val, ",")===0){
return VTQL_Parser::COMMA;
}else{
return VTQL_Parser::COLUMNNAME;
}
}else{
incrementN($lexer, 2);
return VTQL_Parser::FRM;
}
}
}
function handlefrom($lexer, $val){
if((strcasecmp($val, $lexer->mandatory_states[$lexer->current_state])===0)){
incState($lexer);
return VTQL_Parser::FRM;
}
}
function handletable($lexer, $val){
if($lexer->mandatory){
$lexer->current_state =0;
$lexer->mandatory = false;
if(!(strcasecmp($val, $lexer->optional_states[$lexer->current_state])===0)){
return VTQL_Parser::TABLENAME;
}
}
}
function handlewhere($lexer, $val){
global $where_col,$in_started;
$val = trim($val);
if((strcmp($val, "=")===0)){
return VTQL_Parser::EQ;
}else if((strcasecmp($val, $lexer->optional_states[$lexer->current_state])===0)){
return VTQL_Parser::WHERE;
}else if((strcmp($val, "<")===0)){
return VTQL_Parser::LT;
}else if((strcmp($val, "<=")===0)){
return VTQL_Parser::LTE;
}else if((strcmp($val, ">=")===0)){
return VTQL_Parser::GTE;
}else if((strcmp($val, "!=")===0)){
return VTQL_Parser::NE;
}else if((strcmp($val, ">")===0)){
return VTQL_Parser::GT;
}else if((strcmp($val, "(")===0)){
return VTQL_Parser::PARENOPEN;
}else if((strcmp($val, ")")===0)){
if($in_started){
$in_started = false;
$where_col = false;
}
return VTQL_Parser::PARENCLOSE;
}else if((strcasecmp($val, "and")===0)){
return VTQL_Parser::LOGICAL_AND;
}else if((strcasecmp($val, "or")===0)){
return VTQL_Parser::LOGICAL_OR;
}else if(!$where_col){
$where_col = true;
return VTQL_Parser::COLUMNNAME;
}else if((strcasecmp($val, "in")===0)){
$in_started = true;
return VTQL_Parser::IN;
}else if(strcmp($val, ",")===0){
return VTQL_Parser::COMMA;
}else if(strcasecmp($val, "like")===0){
return VTQL_Parser::LIKE;
}else if($where_col){
if(!$in_started){
$where_col = false;
}
return VTQL_Parser::VALUE;
}
}
function handleorderby($lexer, $val){
global $orderby;
if(!$orderby){
$orderby = true;
return VTQL_Parser::ORDERBY;
}
if(strcmp($val, ",")===0){
return VTQL_Parser::COMMA;
}else if(strcasecmp($val, "asc")===0){
return VTQL_Parser::ASC;
}else if(strcasecmp($val, "desc")===0){
return VTQL_Parser::DESC;
}else{
return VTQL_Parser::COLUMNNAME;
}
}
function handlelimit($lexer, $val){
if((strcasecmp($val, "limit")===0)){
return VTQL_Parser::LIMIT;
}else if((strcmp($val, "(")===0)){
return VTQL_Parser::PARENOPEN;
}else if((strcmp($val, ")")===0)){
return VTQL_Parser::PARENCLOSE;
}else if(strcmp($val, ",")===0){
return VTQL_Parser::COMMA;
}else{
return VTQL_Parser::VALUE;
}
}
function handleend($lexer, $val){
return VTQL_Parser::SEMICOLON;
}
class VTQL_Lexer{
private $index;
public $token;
public $value;
public $linenum;
public $state = 1;
private $data;
public $mandatory_states = array('select','column_list','from','table');
public $optional_states = array('where', 'orderby', 'limit');
public $mandatory ;
public $current_state ;
function __construct($data)
{
$this->index = 0;
$this->data = $data;
$this->linenum = 1;
$this->mandatory = true;
$this->current_state = 0;
}
function __toString(){
return $this->token."";
}
private $_yy_state = 1;
private $_yy_stack = array();
function yylex()
{
return $this->{'yylex' . $this->_yy_state}();
}
function yypushstate($state)
{
array_push($this->_yy_stack, $this->_yy_state);
$this->_yy_state = $state;
}
function yypopstate()
{
$this->_yy_state = array_pop($this->_yy_stack);
}
function yybegin($state)
{
$this->_yy_state = $state;
}
function yylex1()
{
$tokenMap = array (
1 => 2,
4 => 0,
);
if ($this->index >= strlen($this->data)) {
return false; // end of input
}
$yy_global_pattern = "/^((\\w+|'(?:[^']|'')+'|\\(|\\)|(\\+|-)?\\d+|,|\\*|(?!<|>)=|<(?!=)|>(?!=)|<=|>=|!=|;))|^([ \t\r\n]+)/";
do {
if (preg_match($yy_global_pattern, substr($this->data, $this->index), $yymatches)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
throw new Exception('Error: lexing failed because a rule matched' .
'an empty string. Input "' . substr($this->data,
$this->index, 5) . '... state INITR');
}
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
if ($tokenMap[$this->token]) {
// extract sub-patterns for passing to lex function
$yysubmatches = array_slice($yysubmatches, $this->token + 1,
$tokenMap[$this->token]);
} else {
$yysubmatches = array();
}
$this->value = current($yymatches); // token value
$r = $this->{'yy_r1_' . $this->token}($yysubmatches);
if ($r === null) {
$this->index += strlen($this->value);
$this->linenum += substr_count("\n", $this->value);
// accept this token
return true;
} elseif ($r === true) {
// we have changed state
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->index += strlen($this->value);
$this->linenum += substr_count("\n", $this->value);
if ($this->index >= strlen($this->data)) {
return false; // end of input
}
// skip this token
continue;
} else { $yy_yymore_patterns = array(
1 => "^([ \t\r\n]+)",
4 => "",
);
// yymore is needed
do {
if (!strlen($yy_yymore_patterns[$this->token])) {
throw new Exception('cannot do yymore for the last token');
}
if (preg_match($yy_yymore_patterns[$this->token],
substr($this->data, $this->index), $yymatches)) {
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
next($yymatches); // skip global match
$this->token = key($yymatches); // token number
$this->value = current($yymatches); // token value
$this->linenum = substr_count("\n", $this->value);
}
} while ($this->{'yy_r1_' . $this->token}() !== null);
// accept
$this->index += strlen($this->value);
$this->linenum += substr_count("\n", $this->value);
return true;
}
} else {
throw new Exception('Unexpected input at line' . $this->linenum .
': ' . $this->data[$this->index]);
}
break;
} while (true);
} // end function
const INITR = 1;
function yy_r1_1($yy_subpatterns)
{
global $orderby;
//echo "<br> ql state: ",$this->current_state," ",$this->value,"<br>";
if($this->mandatory){
//echo "<br> ql state: ",$this->current_state," ",$this->value,"<br>";
$handler = 'handle'.$this->mandatory_states[$this->current_state];
$this->token = $handler($this, $this->value);
}else{
$str = $this->value;
if(strcmp($this->value, ";")===0){
$this->token = handleend($this, $this->value);
return;
}
if(strcasecmp($this->value, "order")===0){
$orderby = true;
return false;
}else if(strcasecmp($this->value, "by") ===0 && $orderby ===true){
$orderby = false;
$this->current_state = 1;
}
$index = array_search(strtolower($str), $this->optional_states, true);
if($index !== false){
$this->current_state = $index;
}
$handler = 'handle'.$this->optional_states[$this->current_state];
$this->token = $handler($this, $this->value);
}//$this->yypushstate($this->value);
}
function yy_r1_4($yy_subpatterns)
{
return false;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,337 @@
<?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 'include/Webservices/VtigerCRMActorMeta.php';
class VtigerActorOperation extends WebserviceEntityOperation {
protected $entityTableName;
protected $moduleFields;
protected $isEntity = false;
protected $element;
protected $id;
public function __construct($webserviceObject,$user,$adb,$log){
parent::__construct($webserviceObject,$user,$adb,$log);
$this->entityTableName = $this->getActorTables();
if($this->entityTableName === null){
throw new WebServiceException(WebServiceErrorCode::$UNKOWNENTITY,"Entity is not associated with any tables");
}
$this->meta = $this->getMetaInstance();
$this->moduleFields = null;
$this->element = null;
$this->id = null;
}
protected function getMetaInstance(){
if(empty(WebserviceEntityOperation::$metaCache[$this->webserviceObject->getEntityName()][$this->user->id])){
WebserviceEntityOperation::$metaCache[$this->webserviceObject->getEntityName()][$this->user->id]
= new VtigerCRMActorMeta($this->entityTableName,$this->webserviceObject,$this->pearDB,$this->user);
}
return WebserviceEntityOperation::$metaCache[$this->webserviceObject->getEntityName()][$this->user->id];
}
protected function getActorTables(){
static $actorTables = array();
if(isset($actorTables[$this->webserviceObject->getEntityName()])){
return $actorTables[$this->webserviceObject->getEntityName()];
}
$sql = 'select table_name from vtiger_ws_entity_tables where webservice_entity_id=?';
$result = $this->pearDB->pquery($sql,array($this->webserviceObject->getEntityId()));
$tableName = null;
if($result){
$rowCount = $this->pearDB->num_rows($result);
for($i=0;$i<$rowCount;++$i){
$row = $this->pearDB->query_result_rowdata($result,$i);
$tableName = $row['table_name'];
}
// Cache the result for further re-use
$actorTables[$this->webserviceObject->getEntityName()] = $tableName;
}
return $tableName;
}
public function getMeta(){
return $this->meta;
}
protected function getNextId($elementType,$element){
if(strcasecmp($elementType,'Groups') === 0){
$tableName="vtiger_users";
}else{
$tableName = $this->entityTableName;
}
$meta = $this->getMeta();
if(strcasecmp($elementType,'Groups') !== 0 && strcasecmp($elementType,'Users') !== 0) {
$sql = "update $tableName"."_seq set id=(select max(".$meta->getIdColumn().")
from $tableName)";
$this->pearDB->pquery($sql,array());
}
$id = $this->pearDB->getUniqueId($tableName);
return $id;
}
public function __create($elementType,$element){
require_once 'include/utils/utils.php';
$db = PearDatabase::getInstance();
$this->id=$this->getNextId($elementType, $element);
$element[$this->meta->getObectIndexColumn()] = $this->id;
//Insert into group vtiger_table
$query = "insert into {$this->entityTableName}(".implode(',',array_keys($element)).
") values(".generateQuestionMarks(array_keys($element)).")";
$result = null;
$transactionSuccessful = vtws_runQueryAsTransaction($query, array_values($element),
$result);
return $transactionSuccessful;
}
public function create($elementType,$element){
$element = DataTransform::sanitizeForInsert($element,$this->meta);
$element = $this->restrictFields($element);
$success = $this->__create($elementType,$element);
if(!$success){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return $this->retrieve(vtws_getId($this->meta->getEntityId(),$this->id));
}
protected function restrictFields($element, $selectedOnly = false){
$fields = $this->getModuleFields();
$newElement = array();
foreach ($fields as $field) {
if(isset($element[$field['name']])){
$newElement[$field['name']] = $element[$field['name']];
}else if($field['name'] != 'id' && $selectedOnly == false){
$newElement[$field['name']] = '';
}
}
return $newElement;
}
public function __retrieve($id){
$query = "select * from {$this->entityTableName} where {$this->meta->getObectIndexColumn()}=?";
$transactionSuccessful = vtws_runQueryAsTransaction($query,array($id),$result);
if(!$transactionSuccessful){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
$db = $this->pearDB;
if($result){
$rowCount = $db->num_rows($result);
if($rowCount >0){
$this->element = $db->query_result_rowdata($result,0);
return true;
}
}
return false;
}
public function retrieve($id){
$ids = vtws_getIdComponents($id);
$elemId = $ids[1];
$success = $this->__retrieve($elemId);
if(!$success){
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND,
"Record not found");
}
$element = $this->getElement();
return DataTransform::filterAndSanitize($element,$this->meta);
}
public function __update($element,$id){
$columnStr = 'set '.implode('=?,',array_keys($element)).' =? ';
$query = 'update '.$this->entityTableName.' '.$columnStr.'where '.
$this->meta->getObectIndexColumn().'=?';
$params = array_values($element);
array_push($params,$id);
$result = null;
$transactionSuccessful = vtws_runQueryAsTransaction($query,$params,$result);
return $transactionSuccessful;
}
public function update($element){
$ids = vtws_getIdComponents($element["id"]);
$element = DataTransform::sanitizeForInsert($element,$this->meta);
$element = $this->restrictFields($element);
$success = $this->__update($element,$ids[1]);
if(!$success){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return $this->retrieve(vtws_getId($this->meta->getEntityId(),$ids[1]));
}
public function __revise($element,$id){
$columnStr = 'set '.implode('=?,',array_keys($element)).' =? ';
$query = 'update '.$this->entityTableName.' '.$columnStr.'where '.
$this->meta->getObectIndexColumn().'=?';
$params = array_values($element);
array_push($params,$id);
$result = null;
$transactionSuccessful = vtws_runQueryAsTransaction($query,$params,$result);
return $transactionSuccessful;
}
public function revise($element){
$ids = vtws_getIdComponents($element["id"]);
$element = DataTransform::sanitizeForInsert($element,$this->meta);
$element = $this->restrictFields($element, true);
$success = $this->__retrieve($ids[1]);
if(!$success){
throw new WebServiceException(WebServiceErrorCode::$RECORDNOTFOUND,
"Record not found");
}
$allDetails = $this->getElement();
foreach ($allDetails as $index=>$value) {
if(!isset($element)){
$element[$index] = $value;
}
}
$success = $this->__revise($element,$ids[1]);
if(!$success){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return $this->retrieve(vtws_getId($this->meta->getEntityId(),$ids[1]));
}
public function __delete($elemId){
$result = null;
$query = 'delete from '.$this->entityTableName.' where '.
$this->meta->getObectIndexColumn().'=?';
$transactionSuccessful = vtws_runQueryAsTransaction($query,array($elemId),$result);
return $transactionSuccessful;
}
public function delete($id){
$ids = vtws_getIdComponents($id);
$elemId = $ids[1];
$success = $this->__delete($elemId);
if(!$success){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return array("status"=>"successful");
}
public function describe($elementType){
$app_strings = VTWS_PreserveGlobal::getGlobal('app_strings');
$current_user = vtws_preserveGlobal('current_user',$this->user);;
$label = (isset($app_strings[$elementType]))? $app_strings[$elementType]:$elementType;
$createable = $this->meta->hasWriteAccess();
$updateable = $this->meta->hasWriteAccess();
$deleteable = $this->meta->hasDeleteAccess();
$retrieveable = $this->meta->hasReadAccess();
$fields = $this->getModuleFields();
return array("label"=>$label,"name"=>$elementType,"createable"=>$createable,"updateable"=>$updateable,
"deleteable"=>$deleteable,"retrieveable"=>$retrieveable,"fields"=>$fields,
"idPrefix"=>$this->meta->getEntityId(),'isEntity'=>$this->isEntity,'labelFields'=>$this->meta->getNameFields());
}
function getModuleFields(){
$app_strings = VTWS_PreserveGlobal::getGlobal('app_strings');
if($this->moduleFields === null){
$fields = array();
$moduleFields = $this->meta->getModuleFields();
foreach ($moduleFields as $fieldName=>$webserviceField) {
array_push($fields,$this->getDescribeFieldArray($webserviceField));
}
$label = ($app_strings[$this->meta->getObectIndexColumn()])? $app_strings[$this->meta->getObectIndexColumn()]:
$this->meta->getObectIndexColumn();
$this->moduleFields = $fields;
}
return $this->moduleFields;
}
function getDescribeFieldArray($webserviceField){
$app_strings = VTWS_PreserveGlobal::getGlobal('app_strings');
$fieldLabel = $webserviceField->getFieldLabelKey();
if(isset($app_strings[$fieldLabel])){
$fieldLabel = $app_strings[$fieldLabel];
}
if(strcasecmp($webserviceField->getFieldName(),$this->meta->getObectIndexColumn()) === 0){
return $this->getIdField($fieldLabel);
}
$typeDetails = $this->getFieldTypeDetails($webserviceField);
//set type name, in the type details array.
$typeDetails['name'] = $webserviceField->getFieldDataType();
$editable = $this->isEditable($webserviceField);
$describeArray = array('name'=>$webserviceField->getFieldName(),'label'=>$fieldLabel,'mandatory'=>
$webserviceField->isMandatory(),'type'=>$typeDetails,'nullable'=>$webserviceField->isNullable(),
"editable"=>$editable);
if($webserviceField->hasDefault()){
$describeArray['default'] = $webserviceField->getDefault();
}
return $describeArray;
}
public function query($q){
$parser = new Parser($this->user, $q);
$error = $parser->parse();
if($error){
return $parser->getError();
}
$mysql_query = $parser->getSql();
$meta = $parser->getObjectMetaData();
$this->pearDB->startTransaction();
$result = $this->pearDB->pquery($mysql_query, array());
$error = $this->pearDB->hasFailedTransaction();
$this->pearDB->completeTransaction();
if($error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
$noofrows = $this->pearDB->num_rows($result);
$output = array();
for($i=0; $i<$noofrows; $i++){
$row = $this->pearDB->fetchByAssoc($result,$i);
if(!$meta->hasPermission(EntityMeta::$RETRIEVE,$row["crmid"])){
continue;
}
$output[] = DataTransform::sanitizeDataWithColumn($row,$meta);
}
return $output;
}
protected function getElement(){
return $this->element;
}
}
?>

View File

@ -0,0 +1,282 @@
<?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 VtigerCRMActorMeta extends EntityMeta {
protected $pearDB;
protected static $fieldTypeMapping = array();
function VtigerCRMActorMeta($tableName,$webserviceObject,$adb,$user){
parent::__construct($webserviceObject,$user);
$this->baseTable = $tableName;
$this->idColumn = null;
$this->pearDB = $adb;
$fieldList = $this->getTableFieldList($tableName);
$this->moduleFields = array();
foreach ($fieldList as $field) {
$this->moduleFields[$field->getFieldName()] = $field;
}
$this->pearDB = $adb;
$this->tableList = array($this->baseTable);
$this->tableIndexList = array($this->baseTable=>$this->idColumn);
$this->defaultTableList = array();
}
protected function getTableFieldList($tableName){
$tableFieldList = array();
$factory = WebserviceField::fromArray($this->pearDB,array('tablename'=>$tableName));
$dbTableFields = $factory->getTableFields();
foreach ($dbTableFields as $dbField) {
if($dbField->primary_key){
if($this->idColumn === null){
$this->idColumn = $dbField->name;
}else{
throw new WebServiceException(WebServiceErrorCode::$UNKOWNENTITY,
"Entity table with multi column primary key is not supported");
}
}
$field = $this->getFieldArrayFromDBField($dbField,$tableName);
$webserviceField = WebserviceField::fromArray($this->pearDB,$field);
$fieldDataType = $this->getFieldType($dbField,$tableName);
if($fieldDataType === null){
$fieldDataType = $this->getFieldDataTypeFromDBType($dbField->type);
}
$webserviceField->setFieldDataType($fieldDataType);
if(strcasecmp($fieldDataType,'reference') === 0){
$webserviceField->setReferenceList($this->getReferenceList($dbField,$tableName));
}
array_push($tableFieldList,$webserviceField);
}
return $tableFieldList;
}
protected function getFieldArrayFromDBField($dbField,$tableName){
$field = array();
$field['fieldname'] = $dbField->name;
$field['columnname'] = $dbField->name;
$field['tablename'] = $tableName;
$field['fieldlabel'] = str_replace('_', ' ',$dbField->name);
$field['displaytype'] = 1;
$field['uitype'] = 1;
$fieldDataType = $this->getFieldType($dbField,$tableName);
if($fieldDataType !== null){
$fieldType = $this->getTypeOfDataForType($fieldDataType);
}else{
$fieldType = $this->getTypeOfDataForType($dbField->type);
}
$typeOfData = null;
if(($dbField->not_null && !$dbField->primary_key) || $dbField->unique_key == 1){
$typeOfData = $fieldType.'~M';
}else{
$typeOfData = $fieldType.'~O';
}
$field['typeofdata'] = $typeOfData;
$field['tabid'] = null;
$field['fieldid'] = null;
$field['masseditable'] = 0;
$field['presence'] = '0';
return $field;
}
protected function getReferenceList($dbField, $tableName){
static $referenceList = array();
if(isset($referenceList[$dbField->name])){
return $referenceList[$dbField->name];
}
if(!isset(VtigerCRMActorMeta::$fieldTypeMapping[$tableName][$dbField->name])){
$this->getFieldType($dbField, $tableName);
}
$fieldTypeData = VtigerCRMActorMeta::$fieldTypeMapping[$tableName][$dbField->name];
$referenceTypes = array();
$sql = "select * from vtiger_ws_entity_referencetype where fieldtypeid=?";
$result = $this->pearDB->pquery($sql,array($fieldTypeData['fieldtypeid']));
$numRows = $this->pearDB->num_rows($result);
for($i=0;$i<$numRows;++$i){
array_push($referenceTypes,$this->pearDB->query_result($result,$i,"type"));
}
$referenceList[$dbField->name] = $referenceTypes;
return $referenceTypes;
}
protected function getFieldType($dbField,$tableName){
if(isset(VtigerCRMActorMeta::$fieldTypeMapping[$tableName][$dbField->name])){
if(VtigerCRMActorMeta::$fieldTypeMapping[$tableName][$dbField->name] === 'null'){
return null;
}
$row = VtigerCRMActorMeta::$fieldTypeMapping[$tableName][$dbField->name];
return $row['fieldtype'];
}
$sql = "select * from vtiger_ws_entity_fieldtype where table_name=? and field_name=?;";
$result = $this->pearDB->pquery($sql,array($tableName,$dbField->name));
$rowCount = $this->pearDB->num_rows($result);
if($rowCount > 0){
$row = $this->pearDB->query_result_rowdata($result,0);
VtigerCRMActorMeta::$fieldTypeMapping[$tableName][$dbField->name] = $row;
return $row['fieldtype'];
}else{
VtigerCRMActorMeta::$fieldTypeMapping[$tableName][$dbField->name] = 'null';
return null;
}
}
protected function getTypeOfDataForType($type){
switch($type){
case 'email': return 'E';
case 'password': return 'P';
case 'date': return 'D';
case 'datetime': return 'DT';
case 'timestamp': return 'T';
case 'int':
case 'integer': return 'I';
case 'decimal':
case 'numeric': return 'N';
case 'varchar':
case 'text':
default: return 'V';
}
}
protected function getFieldDataTypeFromDBType($type){
switch($type){
case 'date': return 'date';
case 'datetime': return 'datetime';
case 'timestamp': return 'time';
case 'int':
case 'integer': return 'integer';
case 'real':
case 'decimal':
case 'numeric': return 'double';
case 'text': return 'text';
case 'varchar': return 'string';
default: return $type;
}
}
public function hasPermission($operation,$webserviceId){
if(is_admin($this->user)){
return true;
}else{
if(strcmp($operation,EntityMeta::$RETRIEVE)===0){
return true;
}
return false;
}
}
public function hasAssignPrivilege($ownerWebserviceId){
if(is_admin($this->user)){
return true;
}else{
$idComponents = vtws_getIdComponents($webserviceId);
$userId=$idComponents[1];
if($this->user->id === $userId){
return true;
}
return false;
}
}
public function hasDeleteAccess(){
if(is_admin($this->user)){
return true;
}else{
return false;
}
}
public function hasAccess(){
return true;
}
public function hasReadAccess(){
return true;
}
public function hasWriteAccess(){
if(is_admin($this->user)){
return true;
}else{
return false;
}
}
public function getEntityName(){
return $this->webserviceObject->getEntityName();
}
public function getEntityId(){
return $this->webserviceObject->getEntityId();
}
function getObjectEntityName($webserviceId){
$idComponents = vtws_getIdComponents($webserviceId);
$id=$idComponents[1];
if($this->exists($id)){
return $this->webserviceObject->getEntityName();
}
return null;
}
function exists($recordId){
$exists = false;
$sql = 'select * from '.$this->baseTable.' where '.$this->getObectIndexColumn().'=?';
$result = $this->pearDB->pquery($sql , array($recordId));
if($result != null && isset($result)){
if($this->pearDB->num_rows($result)>0){
$exists = true;
}
}
return $exists;
}
public function getNameFields(){
$query = "select name_fields from vtiger_ws_entity_name where entity_id = ?";
$result = $this->pearDB->pquery($query, array($this->objectId));
$fieldNames = '';
if($result){
$rowCount = $this->pearDB->num_rows($result);
if($rowCount > 0){
$fieldNames = $this->pearDB->query_result($result,0,'name_fields');
}
}
return $fieldNames;
}
public function getName($webserviceId){
$idComponents = vtws_getIdComponents($webserviceId);
$entityId = $idComponents[0];
$id=$idComponents[1];
$nameList = vtws_getActorEntityNameById($entityId, array($id));
return $nameList[$id];
}
public function getEntityAccessControlQuery() {
return '';
}
public function getEntityDeletedQuery() {
if($this->getEntityName() == 'Currency'){
return 'vtiger_currency_info.deleted=0';
}
return '';
}
public function isModuleEntity() {
return false;
}
}
?>

View File

@ -0,0 +1,215 @@
<?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 VtigerCRMObject{
private $moduleName ;
private $moduleId ;
private $instance ;
function VtigerCRMObject($moduleCredential, $isId=false){
if($isId){
$this->moduleId = $moduleCredential;
$this->moduleName = $this->getObjectTypeName($this->moduleId);
}else{
$this->moduleName = $moduleCredential;
$this->moduleId = $this->getObjectTypeId($this->moduleName);
}
$this->instance = null;
$this->getInstance();
}
public function getModuleName(){
return $this->moduleName;
}
public function getModuleId(){
return $this->moduleId;
}
public function getInstance(){
if($this->instance == null){
$this->instance = $this->getModuleClassInstance($this->moduleName);
}
return $this->instance;
}
public function getObjectId(){
if($this->instance==null){
$this->getInstance();
}
return $this->instance->id;
}
public function setObjectId($id){
if($this->instance==null){
$this->getInstance();
}
$this->instance->id = $id;
}
private function titleCase($str){
$first = substr($str, 0, 1);
return strtoupper($first).substr($str,1);
}
private function getObjectTypeId($objectName){
// Use getTabid API
$tid = getTabid($objectName);
if($tid === false) {
global $adb;
$sql = "select * from vtiger_tab where name=?;";
$params = array($objectName);
$result = $adb->pquery($sql, $params);
$data1 = $adb->fetchByAssoc($result,1,false);
$tid = $data1["tabid"];
}
// END
return $tid;
}
private function getModuleClassInstance($moduleName){
return CRMEntity::getInstance($moduleName);
}
private function getObjectTypeName($moduleId){
return getTabModuleName($moduleId);
}
private function getTabName(){
if($this->moduleName == 'Events'){
return 'Calendar';
}
return $this->moduleName;
}
public function read($id){
global $adb;
$error = false;
$adb->startTransaction();
$this->instance->retrieve_entity_info($id,$this->getTabName());
$error = $adb->hasFailedTransaction();
$adb->completeTransaction();
return !$error;
}
public function create($element){
global $adb;
$error = false;
foreach($element as $k=>$v){
$this->instance->column_fields[$k] = $v;
}
$adb->startTransaction();
$this->instance->Save($this->getTabName());
$error = $adb->hasFailedTransaction();
$adb->completeTransaction();
return !$error;
}
public function update($element){
global $adb;
$error = false;
foreach($element as $k=>$v){
$this->instance->column_fields[$k] = $v;
}
$adb->startTransaction();
$this->instance->mode = "edit";
$this->instance->Save($this->getTabName());
$error = $adb->hasFailedTransaction();
$adb->completeTransaction();
return !$error;
}
public function revise($element){
global $adb;
$error = false;
$error = $this->read($this->getObjectId());
if($error == false){
return $error;
}
foreach($element as $k=>$v){
$this->instance->column_fields[$k] = $v;
}
//added to fix the issue of utf8 characters
foreach($this->instance->column_fields as $key=>$value){
$this->instance->column_fields[$key] = decode_html($value);
}
$adb->startTransaction();
$this->instance->mode = "edit";
$this->instance->Save($this->getTabName());
$error = $adb->hasFailedTransaction();
$adb->completeTransaction();
return !$error;
}
public function delete($id){
global $adb;
$error = false;
$adb->startTransaction();
DeleteEntity($this->getTabName(), $this->getTabName(), $this->instance, $id,$returnid);
$error = $adb->hasFailedTransaction();
$adb->completeTransaction();
return !$error;
}
public function getFields(){
return $this->instance->column_fields;
}
function exists($id){
global $adb;
$exists = false;
$sql = "select * from vtiger_crmentity where crmid=? and deleted=0";
$result = $adb->pquery($sql , array($id));
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
$exists = true;
}
}
return $exists;
}
function getSEType($id){
global $adb;
$seType = null;
$sql = "select * from vtiger_crmentity where crmid=? and deleted=0";
$result = $adb->pquery($sql , array($id));
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
$seType = $adb->query_result($result,0,"setype");
}
}
return $seType;
}
}
?>

View File

@ -0,0 +1,521 @@
<?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 VtigerCRMObjectMeta extends EntityMeta {
private $tabId;
private $meta;
private $assign;
private $hasAccess;
private $hasReadAccess;
private $hasWriteAccess;
private $hasDeleteAccess;
private $assignUsers;
function VtigerCRMObjectMeta($webserviceObject,$user){
parent::__construct($webserviceObject,$user);
$this->columnTableMapping = null;
$this->fieldColumnMapping = null;
$this->userAccessibleColumns = null;
$this->mandatoryFields = null;
$this->emailFields = null;
$this->referenceFieldDetails = null;
$this->ownerFields = null;
$this->moduleFields = array();
$this->hasAccess = false;
$this->hasReadAccess = false;
$this->hasWriteAccess = false;
$this->hasDeleteAccess = false;
$instance = vtws_getModuleInstance($this->webserviceObject);
$this->idColumn = $instance->tab_name_index[$instance->table_name];
$this->baseTable = $instance->table_name;
$this->tableList = $instance->tab_name;
$this->tableIndexList = $instance->tab_name_index;
if(in_array('vtiger_crmentity',$instance->tab_name)){
$this->defaultTableList = array('vtiger_crmentity');
}else{
$this->defaultTableList = array();
}
$this->tabId = null;
}
/**
* returns tabid of the current object.
* @return Integer
*/
public function getTabId(){
if($this->tabId == null){
$this->tabId = getTabid($this->objectName);
}
return $this->tabId;
}
/**
* returns tabid that can be consumed for database lookup purpose generally, events and
* calendar are treated as the same module
* @return Integer
*/
public function getEffectiveTabId() {
return getTabid($this->getTabName());
}
public function getTabName(){
if($this->objectName == 'Events'){
return 'Calendar';
}
return $this->objectName;
}
private function computeAccess(){
global $adb;
$active = vtlib_isModuleActive($this->getTabName());
if($active == false){
$this->hasAccess = false;
$this->hasReadAccess = false;
$this->hasWriteAccess = false;
$this->hasDeleteAccess = false;
return;
}
require('user_privileges/user_privileges_'.$this->user->id.'.php');
if($is_admin == true || $profileGlobalPermission[1] == 0 || $profileGlobalPermission[2] == 0){
$this->hasAccess = true;
$this->hasReadAccess = true;
$this->hasWriteAccess = true;
$this->hasDeleteAccess = true;
}else{
//TODO get oer sort out the preference among profile2tab and profile2globalpermissions.
//TODO check whether create/edit seperate controls required for web sevices?
$profileList = getCurrentUserProfileList();
$sql = "select * from vtiger_profile2globalpermissions where profileid in (".generateQuestionMarks($profileList).");";
$result = $adb->pquery($sql,array($profileList));
$noofrows = $adb->num_rows($result);
//globalactionid=1 is view all action.
//globalactionid=2 is edit all action.
for($i=0; $i<$noofrows; $i++){
$permission = $adb->query_result($result,$i,"globalactionpermission");
$globalactionid = $adb->query_result($result,$i,"globalactionid");
if($permission != 1 || $permission != "1"){
$this->hasAccess = true;
if($globalactionid == 2 || $globalactionid == "2"){
$this->hasWriteAccess = true;
$this->hasDeleteAccess = true;
}else{
$this->hasReadAccess = true;
}
}
}
$sql = 'select * from vtiger_profile2tab where profileid in ('.generateQuestionMarks($profileList).') and tabid = ?;';
$result = $adb->pquery($sql,array($profileList,$this->getTabId()));
$standardDefined = false;
$permission = $adb->query_result($result,1,"permissions");
if($permission == 1 || $permission == "1"){
$this->hasAccess = false;
return;
}else{
$this->hasAccess = true;
}
//operation=2 is delete operation.
//operation=0 or 1 is create/edit operation. precise 0 create and 1 edit.
//operation=3 index or popup. //ignored for websevices.
//operation=4 is view operation.
$sql = "select * from vtiger_profile2standardpermissions where profileid in (".generateQuestionMarks($profileList).") and tabid=?";
$result = $adb->pquery($sql,array($profileList,$this->getTabId()));
$noofrows = $adb->num_rows($result);
for($i=0; $i<$noofrows; $i++){
$standardDefined = true;
$permission = $adb->query_result($result,$i,"permissions");
$operation = $adb->query_result($result,$i,"Operation");
if(!$operation){
$operation = $adb->query_result($result,$i,"operation");
}
if($permission != 1 || $permission != "1"){
$this->hasAccess = true;
if($operation == 0 || $operation == "0"){
$this->hasWriteAccess = true;
}else if($operation == 1 || $operation == "1"){
$this->hasWriteAccess = true;
}else if($operation == 2 || $operation == "2"){
$this->hasDeleteAccess = true;
}else if($operation == 4 || $operation == "4"){
$this->hasReadAccess = true;
}
}
}
if(!$standardDefined){
$this->hasReadAccess = true;
$this->hasWriteAccess = true;
$this->hasDeleteAccess = true;
}
}
}
function hasAccess(){
if(!$this->meta){
$this->retrieveMeta();
}
return $this->hasAccess;
}
function hasWriteAccess(){
if(!$this->meta){
$this->retrieveMeta();
}
return $this->hasWriteAccess;
}
function hasReadAccess(){
if(!$this->meta){
$this->retrieveMeta();
}
return $this->hasReadAccess;
}
function hasDeleteAccess(){
if(!$this->meta){
$this->retrieveMeta();
}
return $this->hasDeleteAccess;
}
function hasPermission($operation,$webserviceId){
$idComponents = vtws_getIdComponents($webserviceId);
$id=$idComponents[1];
$permitted = isPermitted($this->getTabName(),$operation,$id);
if(strcmp($permitted,"yes")===0){
return true;
}
return false;
}
function hasAssignPrivilege($webserviceId){
global $adb;
// administrator's have assign privilege
if(is_admin($this->user)) return true;
$idComponents = vtws_getIdComponents($webserviceId);
$userId=$idComponents[1];
$ownerTypeId = $idComponents[0];
if($userId == null || $userId =='' || $ownerTypeId == null || $ownerTypeId ==''){
return false;
}
$webserviceObject = VtigerWebserviceObject::fromId($adb,$ownerTypeId);
if(strcasecmp($webserviceObject->getEntityName(),"Users")===0){
if($userId == $this->user->id){
return true;
}
if(!$this->assign){
$this->retrieveUserHierarchy();
}
if(in_array($userId,array_keys($this->assignUsers))){
return true;
}else{
return false;
}
}elseif(strcasecmp($webserviceObject->getEntityName(),"Groups") === 0){
$tabId = $this->getTabId();
$groups = vtws_getUserAccessibleGroups($tabId, $this->user);
foreach ($groups as $group) {
if($group['id'] == $userId){
return true;
}
}
return false;
}
}
function getUserAccessibleColumns(){
if(!$this->meta){
$this->retrieveMeta();
}
return parent::getUserAccessibleColumns();
}
public function getModuleFields() {
if(!$this->meta){
$this->retrieveMeta();
}
return parent::getModuleFields();
}
function getColumnTableMapping(){
if(!$this->meta){
$this->retrieveMeta();
}
return parent::getColumnTableMapping();
}
function getFieldColumnMapping(){
if(!$this->meta){
$this->retrieveMeta();
}
if($this->fieldColumnMapping === null){
$this->fieldColumnMapping = array();
foreach ($this->moduleFields as $fieldName=>$webserviceField) {
if(strcasecmp($webserviceField->getFieldDataType(),'file') !== 0){
$this->fieldColumnMapping[$fieldName] = $webserviceField->getColumnName();
}
}
$this->fieldColumnMapping['id'] = $this->idColumn;
}
return $this->fieldColumnMapping;
}
function getMandatoryFields(){
if(!$this->meta){
$this->retrieveMeta();
}
return parent::getMandatoryFields();
}
function getReferenceFieldDetails(){
if(!$this->meta){
$this->retrieveMeta();
}
return parent::getReferenceFieldDetails();
}
function getOwnerFields(){
if(!$this->meta){
$this->retrieveMeta();
}
return parent::getOwnerFields();
}
function getEntityName(){
return $this->objectName;
}
function getEntityId(){
return $this->objectId;
}
function getEmailFields(){
if(!$this->meta){
$this->retrieveMeta();
}
return parent::getEmailFields();
}
function getFieldIdFromFieldName($fieldName){
if(!$this->meta){
$this->retrieveMeta();
}
if(isset($this->moduleFields[$fieldName])){
$webserviceField = $this->moduleFields[$fieldName];
return $webserviceField->getFieldId();
}
return null;
}
function retrieveMeta(){
require_once('modules/CustomView/CustomView.php');
$current_user = vtws_preserveGlobal('current_user',$this->user);
$theme = vtws_preserveGlobal('theme',$this->user->theme);
$default_language = VTWS_PreserveGlobal::getGlobal('default_language');
$current_language = vtws_preserveGlobal('current_language',$default_language);
$this->computeAccess();
$cv = new CustomView();
$module_info = $cv->getCustomViewModuleInfo($this->getTabName());
$blockArray = array();
foreach($cv->module_list[$this->getTabName()] as $label=>$blockList){
$blockArray = array_merge($blockArray,explode(',',$blockList));
}
$this->retrieveMetaForBlock($blockArray);
$this->meta = true;
VTWS_PreserveGlobal::flush();
}
private function retrieveUserHierarchy(){
$heirarchyUsers = get_user_array(false,"ACTIVE",$this->user->id);
$groupUsers = vtws_getUsersInTheSameGroup($this->user->id);
$this->assignUsers = $heirarchyUsers+$groupUsers;
$this->assign = true;
}
private function retrieveMetaForBlock($block){
global $adb;
$tabid = $this->getTabId();
require('user_privileges/user_privileges_'.$this->user->id.'.php');
if($is_admin == true || $profileGlobalPermission[1] == 0 || $profileGlobalPermission[2] ==0){
$sql = "select *, '0' as readonly from vtiger_field where tabid =? and block in (".generateQuestionMarks($block).") and displaytype in (1,2,3,4)";
$params = array($tabid, $block);
}else{
$profileList = getCurrentUserProfileList();
if (count($profileList) > 0) {
$sql = "SELECT vtiger_field.*, vtiger_profile2field.readonly
FROM vtiger_field
INNER JOIN vtiger_profile2field
ON vtiger_profile2field.fieldid = vtiger_field.fieldid
INNER JOIN vtiger_def_org_field
ON vtiger_def_org_field.fieldid = vtiger_field.fieldid
WHERE vtiger_field.tabid =? AND vtiger_profile2field.visible = 0
AND vtiger_profile2field.profileid IN (". generateQuestionMarks($profileList) .")
AND vtiger_def_org_field.visible = 0 and vtiger_field.block in (".generateQuestionMarks($block).") and vtiger_field.displaytype in (1,2,3,4) and vtiger_field.presence in (0,2) group by columnname";
$params = array($tabid, $profileList, $block);
} else {
$sql = "SELECT vtiger_field.*, vtiger_profile2field.readonly
FROM vtiger_field
INNER JOIN vtiger_profile2field
ON vtiger_profile2field.fieldid = vtiger_field.fieldid
INNER JOIN vtiger_def_org_field
ON vtiger_def_org_field.fieldid = vtiger_field.fieldid
WHERE vtiger_field.tabid=?
AND vtiger_profile2field.visible = 0
AND vtiger_def_org_field.visible = 0 and vtiger_field.block in (".generateQuestionMarks($block).") and vtiger_field.displaytype in (1,2,3,4) and vtiger_field.presence in (0,2) group by columnname";
$params = array($tabid, $block);
}
}
// Bulk Save Mode: Group by is not required!?
if(CRMEntity::isBulkSaveMode()) {
$sql = preg_replace("/group by [^ ]*/", " ", $sql);
}
// END
$result = $adb->pquery($sql,$params);
$noofrows = $adb->num_rows($result);
$referenceArray = array();
$knownFieldArray = array();
for($i=0; $i<$noofrows; $i++){
$fieldname = $adb->query_result($result,$i,"fieldname");
if(strcasecmp($fieldname,'imagename')===0){
continue;
}
$webserviceField = WebserviceField::fromQueryResult($adb,$result,$i);
$this->moduleFields[$webserviceField->getFieldName()] = $webserviceField;
}
}
function getObjectEntityName($webserviceId){
global $adb;
$idComponents = vtws_getIdComponents($webserviceId);
$id=$idComponents[1];
$seType = null;
if($this->objectName == 'Users'){
$sql = "select user_name from vtiger_users where id=? and deleted=0";
$result = $adb->pquery($sql , array($id));
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
$seType = 'Users';
}
}
}else{
$sql = "select * from vtiger_crmentity where crmid=? and deleted=0";
$result = $adb->pquery($sql , array($id));
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
$seType = $adb->query_result($result,0,"setype");
if($seType == "Calendar"){
$seType = vtws_getCalendarEntityType($id);
}
}
}
}
return $seType;
}
function exists($recordId){
global $adb;
$exists = false;
$sql = '';
if($this->objectName == 'Users'){
$sql = "select * from vtiger_users where id=? and deleted=0 and status='Active'";
}else{
$sql = "select * from vtiger_crmentity where crmid=? and deleted=0 and setype='".
$this->getTabName()."'";
}
$result = $adb->pquery($sql , array($recordId));
if($result != null && isset($result)){
if($adb->num_rows($result)>0){
$exists = true;
}
}
return $exists;
}
public function getNameFields(){
global $adb;
$query = "select fieldname,tablename,entityidfield from vtiger_entityname where tabid = ?";
$result = $adb->pquery($query, array($this->getEffectiveTabId()));
$fieldNames = '';
if($result){
$rowCount = $adb->num_rows($result);
if($rowCount > 0){
$fieldNames = $adb->query_result($result,0,'fieldname');
}
}
return $fieldNames;
}
public function getName($webserviceId){
$idComponents = vtws_getIdComponents($webserviceId);
$id=$idComponents[1];
$nameList = getEntityName($this->getTabName(),array($id));
return $nameList[$id];
}
public function getEntityAccessControlQuery(){
$accessControlQuery = '';
$instance = vtws_getModuleInstance($this->webserviceObject);
if($this->getTabName() != 'Users') {
$accessControlQuery = $instance->getNonAdminAccessControlQuery($this->getTabName(),
$this->user);
}
return $accessControlQuery;
}
public function getJoinClause($tableName) {
$instance = vtws_getModuleInstance($this->webserviceObject);
return $instance->getJoinClause($tableName);
}
public function isModuleEntity() {
return true;
}
}
?>

View File

@ -0,0 +1,51 @@
<?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 'include/Webservices/VtigerActorOperation.php';
/**
* Description of VtigerCompanyDetails
*
* @author MAK
*/
class VtigerCompanyDetails extends VtigerActorOperation {
public function create($elementType, $element) {
$db = PearDatabase::getInstance();
$sql = 'select * from vtiger_organizationdetails';
$result = $db->pquery($sql,$params);
$rowCount = $db->num_rows($result);
if($rowCount > 0) {
$id = $db->query_result($result,0,'organization_id');
$meta = $this->getMeta();
$element['id'] = vtws_getId($meta->getEntityId(), $id);
return $this->update($element);
}else{
$element = $this->handleFileUpload($element);
return parent::create($elementType, $element);
}
}
function handleFileUpload($element) {
$fileFieldList = $this->meta->getFieldListByType('file');
foreach ($fileFieldList as $field) {
$fieldname = $field->getFieldName();
if(is_array($_FILES[$fieldname])) {
$element[$fieldname] = vtws_CreateCompanyLogoFile($fieldname);
}
}
return $element;
}
public function update($element) {
$element = $this->handleFileUpload($element);
return parent::update($element);
}
}
?>

View File

@ -0,0 +1,237 @@
<?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 VtigerModuleOperation extends WebserviceEntityOperation {
protected $tabId;
protected $isEntity = true;
public function VtigerModuleOperation($webserviceObject,$user,$adb,$log){
parent::__construct($webserviceObject,$user,$adb,$log);
$this->meta = $this->getMetaInstance();
$this->tabId = $this->meta->getTabId();
}
protected function getMetaInstance(){
if(empty(WebserviceEntityOperation::$metaCache[$this->webserviceObject->getEntityName()][$this->user->id])){
WebserviceEntityOperation::$metaCache[$this->webserviceObject->getEntityName()][$this->user->id] = new VtigerCRMObjectMeta($this->webserviceObject,$this->user);
}
return WebserviceEntityOperation::$metaCache[$this->webserviceObject->getEntityName()][$this->user->id];
}
public function create($elementType,$element){
$crmObject = new VtigerCRMObject($elementType, false);
$element = DataTransform::sanitizeForInsert($element,$this->meta);
$error = $crmObject->create($element);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
$id = $crmObject->getObjectId();
// Bulk Save Mode
if(CRMEntity::isBulkSaveMode()) {
// Avoiding complete read, as during bulk save mode, $result['id'] is enough
return array('id' => vtws_getId($this->meta->getEntityId(), $id) );
}
$error = $crmObject->read($id);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return DataTransform::filterAndSanitize($crmObject->getFields(),$this->meta);
}
public function retrieve($id){
$ids = vtws_getIdComponents($id);
$elemid = $ids[1];
$crmObject = new VtigerCRMObject($this->tabId, true);
$error = $crmObject->read($elemid);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return DataTransform::filterAndSanitize($crmObject->getFields(),$this->meta);
}
public function update($element){
$ids = vtws_getIdComponents($element["id"]);
$element = DataTransform::sanitizeForInsert($element,$this->meta);
$crmObject = new VtigerCRMObject($this->tabId, true);
$crmObject->setObjectId($ids[1]);
$error = $crmObject->update($element);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
$id = $crmObject->getObjectId();
$error = $crmObject->read($id);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return DataTransform::filterAndSanitize($crmObject->getFields(),$this->meta);
}
public function revise($element){
$ids = vtws_getIdComponents($element["id"]);
$element = DataTransform::sanitizeForInsert($element,$this->meta);
$crmObject = new VtigerCRMObject($this->tabId, true);
$crmObject->setObjectId($ids[1]);
$error = $crmObject->revise($element);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
$id = $crmObject->getObjectId();
$error = $crmObject->read($id);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return DataTransform::filterAndSanitize($crmObject->getFields(),$this->meta);
}
public function delete($id){
$ids = vtws_getIdComponents($id);
$elemid = $ids[1];
$crmObject = new VtigerCRMObject($this->tabId, true);
$error = $crmObject->delete($elemid);
if(!$error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
return array("status"=>"successful");
}
public function query($q){
$parser = new Parser($this->user, $q);
$error = $parser->parse();
if($error){
return $parser->getError();
}
$mysql_query = $parser->getSql();
$meta = $parser->getObjectMetaData();
$this->pearDB->startTransaction();
$result = $this->pearDB->pquery($mysql_query, array());
$error = $this->pearDB->hasFailedTransaction();
$this->pearDB->completeTransaction();
if($error){
throw new WebServiceException(WebServiceErrorCode::$DATABASEQUERYERROR,
vtws_getWebserviceTranslatedString('LBL_'.
WebServiceErrorCode::$DATABASEQUERYERROR));
}
$noofrows = $this->pearDB->num_rows($result);
$output = array();
for($i=0; $i<$noofrows; $i++){
$row = $this->pearDB->fetchByAssoc($result,$i);
if(!$meta->hasPermission(EntityMeta::$RETRIEVE,$row["crmid"])){
continue;
}
$output[] = DataTransform::sanitizeDataWithColumn($row,$meta);
}
return $output;
}
public function describe($elementType){
$app_strings = VTWS_PreserveGlobal::getGlobal('app_strings');
$current_user = vtws_preserveGlobal('current_user',$this->user);;
$label = (isset($app_strings[$elementType]))? $app_strings[$elementType]:$elementType;
$createable = (strcasecmp(isPermitted($elementType,EntityMeta::$CREATE),'yes')===0)? true:false;
$updateable = (strcasecmp(isPermitted($elementType,EntityMeta::$UPDATE),'yes')===0)? true:false;
$deleteable = $this->meta->hasDeleteAccess();
$retrieveable = $this->meta->hasReadAccess();
$fields = $this->getModuleFields();
return array("label"=>$label,"name"=>$elementType,"createable"=>$createable,"updateable"=>$updateable,
"deleteable"=>$deleteable,"retrieveable"=>$retrieveable,"fields"=>$fields,
"idPrefix"=>$this->meta->getEntityId(),'isEntity'=>$this->isEntity,'labelFields'=>$this->meta->getNameFields());
}
function getModuleFields(){
$fields = array();
$moduleFields = $this->meta->getModuleFields();
foreach ($moduleFields as $fieldName=>$webserviceField) {
if(((int)$webserviceField->getPresence()) == 1) {
continue;
}
array_push($fields,$this->getDescribeFieldArray($webserviceField));
}
array_push($fields,$this->getIdField($this->meta->getObectIndexColumn()));
return $fields;
}
function getDescribeFieldArray($webserviceField){
$default_language = VTWS_PreserveGlobal::getGlobal('default_language');
require 'modules/'.$this->meta->getTabName()."/language/$default_language.lang.php";
$fieldLabel = $webserviceField->getFieldLabelKey();
if(isset($mod_strings[$fieldLabel])){
$fieldLabel = $mod_strings[$fieldLabel];
}
$typeDetails = $this->getFieldTypeDetails($webserviceField);
//set type name, in the type details array.
$typeDetails['name'] = $webserviceField->getFieldDataType();
$editable = $this->isEditable($webserviceField);
$describeArray = array('name'=>$webserviceField->getFieldName(),'label'=>$fieldLabel,'mandatory'=>
$webserviceField->isMandatory(),'type'=>$typeDetails,'nullable'=>$webserviceField->isNullable(),
"editable"=>$editable);
if($webserviceField->hasDefault()){
$describeArray['default'] = $webserviceField->getDefault();
}
return $describeArray;
}
function getMeta(){
return $this->meta;
}
function getField($fieldName){
$moduleFields = $this->meta->getModuleFields();
return $this->getDescribeFieldArray($moduleFields[$fieldName]);
}
}
?>

View File

@ -0,0 +1,108 @@
<?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 VtigerWebserviceObject{
private $id;
private $name;
private $handlerPath;
private $handlerClass;
private function VtigerWebserviceObject($entityId,$entityName,$handler_path,$handler_class){
$this->id = $entityId;
$this->name = $entityName;
$this->handlerPath = $handler_path;
$this->handlerClass = $handler_class;
}
// Cache variables to enable result re-use
private static $_fromNameCache = array();
static function fromName($adb,$entityName){
$rowData = false;
// If the information not available in cache?
if(!isset(self::$_fromNameCache[$entityName])) {
$result = $adb->pquery("select * from vtiger_ws_entity where name=?",array($entityName));
if($result){
$rowCount = $adb->num_rows($result);
if($rowCount === 1){
$rowData = $adb->query_result_rowdata($result,0);
self::$_fromNameCache[$entityName] = $rowData;
}
}
}
$rowData = self::$_fromNameCache[$entityName];
if($rowData) {
return new VtigerWebserviceObject($rowData['id'],$rowData['name'],
$rowData['handler_path'],$rowData['handler_class']);
}
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied for name");
}
// Cache variables to enable result re-use
private static $_fromIdCache = array();
static function fromId($adb,$entityId){
$rowData = false;
// If the information not available in cache?
if(!isset(self::$_fromIdCache[$entityId])) {
$result = $adb->pquery("select * from vtiger_ws_entity where id=?",array($entityId));
if($result){
$rowCount = $adb->num_rows($result);
if($rowCount === 1){
$rowData = $adb->query_result_rowdata($result,0);
self::$_fromIdCache[$entityId] = $rowData;
}
}
}
$rowData = self::$_fromIdCache[$entityId];
if($rowData) {
return new VtigerWebserviceObject($rowData['id'],$rowData['name'],
$rowData['handler_path'],$rowData['handler_class']);
}
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied for id");
}
static function fromQuery($adb,$query){
$moduleRegex = "/[fF][rR][Oo][Mm]\s+([^\s;]+)/";
$matches = array();
$found = preg_match($moduleRegex,$query,$matches);
if($found === 1){
return VtigerWebserviceObject::fromName($adb,trim($matches[1]));
}
throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED,"Permission to perform the operation is denied for query");
}
public function getEntityName(){
return $this->name;
}
public function getEntityId(){
return $this->id;
}
public function getHandlerPath(){
return $this->handlerPath;
}
public function getHandlerClass(){
return $this->handlerClass;
}
}
?>

View File

@ -0,0 +1,24 @@
<?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("include/Webservices/WebServiceErrorCode.php");
class WebServiceException extends Exception {
public $code;
public $message;
function WebServiceException($errCode,$msg){
$this->code = $errCode;
$this->message = $msg;
}
}
?>

View File

@ -0,0 +1,42 @@
<?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 WebServiceErrorCode {
public static $SESSLIFEOVER = "SESSION_EXPIRED";
public static $REFERENCEINVALID = "REFERENCE_INVALID";
public static $SESSIONIDLE = "SESSION_LEFT_IDLE";
public static $SESSIONIDINVALID = "INVALID_SESSIONID";
public static $INVALIDUSERPWD = "INVALID_USER_CREDENTIALS";
public static $AUTHREQUIRED = "AUTHENTICATION_REQUIRED";
public static $AUTHFAILURE = "AUTHENTICATION_FAILURE";
public static $ACCESSDENIED = "ACCESS_DENIED";
public static $DATABASEQUERYERROR = "DATABASE_QUERY_ERROR";
public static $MANDFIELDSMISSING = "MANDATORY_FIELDS_MISSING";
public static $INVALIDID = "INVALID_ID_ATTRIBUTE";
public static $QUERYSYNTAX = "QUERY_SYNTAX_ERROR";
public static $INVALIDTOKEN = "INVALID_AUTH_TOKEN";
public static $ACCESSKEYUNDEFINED = "ACCESSKEY_UNDEFINED";
public static $RECORDNOTFOUND = "RECORD_NOT_FOUND";
public static $UNKNOWNOPERATION = "UNKNOWN_OPERATION";
public static $INTERNALERROR = "INTERNAL_SERVER_ERROR";
public static $OPERATIONNOTSUPPORTED = "OPERATION_NOT_SUPPORTED";
public static $UNKOWNENTITY = "UNKOWN_ENTITY";
public static $INVALID_POTENTIAL_FOR_CONVERT_LEAD = "INVALID_POTENTIAL_FOR_CONVERTLEAD";
public static $LEAD_ALREADY_CONVERTED = "LEAD_ALREADY_CONVERTED";
public static $LEAD_RELATED_UPDATE_FAILED = "LEAD_RELATEDLIST_UPDATE_FAILED";
public static $FAILED_TO_CREATE_RELATION = "FAILED_TO_CREATE_RELATION";
public static $FAILED_TO_MARK_CONVERTED = "FAILED_TO_MARK_LEAD_CONVERTED";
public static $INVALIDOLDPASSWORD = "INVALID_OLD_PASSWORD";
public static $NEWPASSWORDMISMATCH = "NEW_PASSWORD_MISMATCH";
public static $CHANGEPASSWORDFAILURE = "CHANGE_PASSWORD_FAILURE";
}
?>

View File

@ -0,0 +1,122 @@
<?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 WebserviceEntityOperation{
protected $user;
protected $log;
protected $webserviceObject;
protected $meta;
/**
*
* @var PearDatabase
*/
protected $pearDB;
protected static $metaCache = array();
protected function WebserviceEntityOperation($webserviceObject,$user,$adb,$log){
$this->user = $user;
$this->log = $log;
$this->webserviceObject = $webserviceObject;
$this->pearDB = $adb;
}
public function create($elementType,$element){
throw new WebServiceException(WebServiceErrorCode::$OPERATIONNOTSUPPORTED,
"Operation Create is not supported for this entity");
}
public function retrieve($id){
throw new WebServiceException(WebServiceErrorCode::$OPERATIONNOTSUPPORTED,
"Operation Retrieve is not supported for this entity");
}
public function update($element){
throw new WebServiceException(WebServiceErrorCode::$OPERATIONNOTSUPPORTED,
"Operation Update is not supported for this entity");
}
public function revise($element){
throw new WebServiceException(WebServiceErrorCode::$OPERATIONNOTSUPPORTED,
"Operation Update is not supported for this entity");
}
public function delete($id){
throw new WebServiceException(WebServiceErrorCode::$OPERATIONNOTSUPPORTED,
"Operation delete is not supported for this entity");
}
public function query($q){
throw new WebServiceException(WebServiceErrorCode::$OPERATIONNOTSUPPORTED,
"Operation query is not supported for this entity");
}
public function describe($elementType){
throw new WebServiceException(WebServiceErrorCode::$OPERATIONNOTSUPPORTED,
"Operation describe is not supported for this entity");
}
function getFieldTypeDetails($webserviceField){
global $upload_maxsize;
$typeDetails = array();
switch($webserviceField->getFieldDataType()){
case 'reference': $typeDetails['refersTo'] = $webserviceField->getReferenceList();
break;
case 'multipicklist':
case 'picklist': $typeDetails["picklistValues"] = $webserviceField->getPicklistDetails($webserviceField);
$typeDetails['defaultValue'] = $typeDetails["picklistValues"][0]['value'];
break;
case 'file': $maxUploadSize = 0;
$maxUploadSize = ini_get('upload_max_filesize');
$maxUploadSize = strtolower($maxUploadSize);
$maxUploadSize = explode('m',$maxUploadSize);
$maxUploadSize = $maxUploadSize[0];
if(!is_numeric($maxUploadSize)){
$maxUploadSize = 0;
}
$maxUploadSize = $maxUploadSize * 1000000;
if($upload_maxsize > $maxUploadSize){
$maxUploadSize = $upload_maxsize;
}
$typeDetails['maxUploadFileSize'] = $maxUploadSize;
break;
case 'date': $typeDetails['format'] = $this->user->date_format;
}
return $typeDetails;
}
function isEditable($webserviceField){
if(((int)$webserviceField->getDisplayType()) === 2 || strcasecmp($webserviceField->getFieldDataType(),"autogenerated")
===0 || strcasecmp($webserviceField->getFieldDataType(),"id")===0 || $webserviceField->isReadOnly() == true){
return false;
}
//uitype 70 is vtiger generated fields, such as (of vtiger_crmentity table) createdtime
//and modified time fields.
if($webserviceField->getUIType() == 70 || $webserviceField->getUIType() == 4){
return false;
}
return true;
}
function getIdField($label){
return array('name'=>'id','label'=>$label,'mandatory'=>false,'type'=>'id','editable'=>false,'type'=>
array('name'=>'autogenerated'),'nullable'=>false,'default'=>"");
}
/**
* @return Intance of EntityMeta class.
*
*/
abstract public function getMeta();
abstract protected function getMetaInstance();
}
?>

View File

@ -0,0 +1,397 @@
<?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 WebserviceField{
private $fieldId;
private $uitype;
private $blockId;
private $blockName;
private $nullable;
private $default;
private $tableName;
private $columnName;
private $fieldName;
private $fieldLabel;
private $editable;
private $fieldType;
private $displayType;
private $mandatory;
private $massEditable;
private $tabid;
private $presence;
/**
*
* @var PearDatabase
*/
private $pearDB;
private $typeOfData;
private $fieldDataType;
private $dataFromMeta;
private static $tableMeta = array();
private static $fieldTypeMapping = array();
private $referenceList;
private $defaultValuePresent;
private $explicitDefaultValue;
private $genericUIType = 10;
private $readOnly = 0;
private function __construct($adb,$row){
$this->uitype = $row['uitype'];
$this->blockId = $row['block'];
$this->blockName = null;
$this->tableName = $row['tablename'];
$this->columnName = $row['columnname'];
$this->fieldName = $row['fieldname'];
$this->fieldLabel = $row['fieldlabel'];
$this->displayType = $row['displaytype'];
$this->massEditable = ($row['masseditable'] === '1')? true: false;
$typeOfData = $row['typeofdata'];
$this->presence = $row['presence'];
$this->typeOfData = $typeOfData;
$typeOfData = explode("~",$typeOfData);
$this->mandatory = ($typeOfData[1] == 'M')? true: false;
if($this->uitype == 4){
$this->mandatory = false;
}
$this->fieldType = $typeOfData[0];
$this->tabid = $row['tabid'];
$this->fieldId = $row['fieldid'];
$this->pearDB = $adb;
$this->fieldDataType = null;
$this->dataFromMeta = false;
$this->defaultValuePresent = false;
$this->referenceList = null;
$this->explicitDefaultValue = false;
$this->readOnly = (isset($row['readonly']))? $row['readonly'] : 0;
if(array_key_exists('defaultvalue', $row)) {
$this->setDefault($row['defaultvalue']);
}
}
public static function fromQueryResult($adb,$result,$rowNumber){
return new WebserviceField($adb,$adb->query_result_rowdata($result,$rowNumber));
}
public static function fromArray($adb,$row){
return new WebserviceField($adb,$row);
}
public function getTableName(){
return $this->tableName;
}
public function getFieldName(){
return $this->fieldName;
}
public function getFieldLabelKey(){
return $this->fieldLabel;
}
public function getFieldType(){
return $this->fieldType;
}
public function isMandatory(){
return $this->mandatory;
}
public function getTypeOfData(){
return $this->typeOfData;
}
public function getDisplayType(){
return $this->displayType;
}
public function getMassEditable(){
return $this->massEditable;
}
public function getFieldId(){
return $this->fieldId;
}
public function getDefault(){
if($this->dataFromMeta !== true && $this->explicitDefaultValue !== true){
$this->fillColumnMeta();
}
return $this->default;
}
public function getColumnName(){
return $this->columnName;
}
public function getBlockId(){
return $this->blockId;
}
public function getBlockName(){
if(empty($this->blockName)) {
$this->blockName = getBlockName($this->blockId);
}
return $this->blockName;
}
public function getTabId(){
return $this->tabid;
}
public function isNullable(){
if($this->dataFromMeta !== true){
$this->fillColumnMeta();
}
return $this->nullable;
}
public function hasDefault(){
if($this->dataFromMeta !== true && $this->explicitDefaultValue !== true){
$this->fillColumnMeta();
}
return $this->defaultValuePresent;
}
public function getUIType(){
return $this->uitype;
}
public function isReadOnly() {
if($this->readOnly == 1) return true;
return false;
}
private function setNullable($nullable){
$this->nullable = $nullable;
}
public function setDefault($value){
$this->default = $value;
$this->explicitDefaultValue = true;
$this->defaultValuePresent = true;
}
public function setFieldDataType($dataType){
$this->fieldDataType = $dataType;
}
public function setReferenceList($referenceList){
$this->referenceList = $referenceList;
}
public function getTableFields(){
$tableFields = null;
if(isset(WebserviceField::$tableMeta[$this->getTableName()])){
$tableFields = WebserviceField::$tableMeta[$this->getTableName()];
}else{
$dbMetaColumns = $this->pearDB->database->MetaColumns($this->getTableName());
$tableFields = array();
foreach ($dbMetaColumns as $key => $dbField) {
$tableFields[$dbField->name] = $dbField;
}
WebserviceField::$tableMeta[$this->getTableName()] = $tableFields;
}
return $tableFields;
}
public function fillColumnMeta(){
$tableFields = $this->getTableFields();
foreach ($tableFields as $fieldName => $dbField) {
if(strcmp($fieldName,$this->getColumnName())===0){
$this->setNullable(!$dbField->not_null);
if($dbField->has_default === true && !$this->explicitDefaultValue){
$this->defaultValuePresent = $dbField->has_default;
$this->setDefault($dbField->default_value);
}
}
}
$this->dataFromMeta = true;
}
public function getFieldDataType(){
if($this->fieldDataType === null){
$fieldDataType = $this->getFieldTypeFromUIType();
if($fieldDataType === null){
$fieldDataType = $this->getFieldTypeFromTypeOfData();
}
if($fieldDataType == 'date' || $fieldDataType == 'datetime' || $fieldDataType == 'time') {
$tableFieldDataType = $this->getFieldTypeFromTable();
if($tableFieldDataType == 'datetime'){
$fieldDataType = $tableFieldDataType;
}
}
$this->fieldDataType = $fieldDataType;
}
return $this->fieldDataType;
}
public function getReferenceList(){
static $referenceList = array();
if($this->referenceList === null){
if(isset($referenceList[$this->getFieldId()])){
$this->referenceList = $referenceList[$this->getFieldId()];
return $referenceList[$this->getFieldId()];
}
if(!isset(WebserviceField::$fieldTypeMapping[$this->getUIType()])){
$this->getFieldTypeFromUIType();
}
$fieldTypeData = WebserviceField::$fieldTypeMapping[$this->getUIType()];
$referenceTypes = array();
if($this->getUIType() != $this->genericUIType){
$sql = "select * from vtiger_ws_referencetype where fieldtypeid=?";
$params = array($fieldTypeData['fieldtypeid']);
}else{
$sql = 'select relmodule as type from vtiger_fieldmodulerel where fieldid=?';
$params = array($this->getFieldId());
}
$result = $this->pearDB->pquery($sql,$params);
$numRows = $this->pearDB->num_rows($result);
for($i=0;$i<$numRows;++$i){
array_push($referenceTypes,$this->pearDB->query_result($result,$i,"type"));
}
//to handle hardcoding done for Calendar module todo activities.
if($this->tabid == 9 && $this->fieldName =='parent_id'){
$referenceTypes[] = 'Invoice';
$referenceTypes[] = 'Quotes';
$referenceTypes[] = 'PurchaseOrder';
$referenceTypes[] = 'SalesOrder';
$referenceTypes[] = 'Campaigns';
}
global $current_user;
$types = vtws_listtypes(null, $current_user);
$accessibleTypes = $types['types'];
if(!is_admin($current_user)) {
array_push($accessibleTypes, 'Users');
}
$referenceTypes = array_values(array_intersect($accessibleTypes,$referenceTypes));
$referenceList[$this->getFieldId()] = $referenceTypes;
$this->referenceList = $referenceTypes;
return $referenceTypes;
}
return $this->referenceList;
}
private function getFieldTypeFromTable(){
$tableFields = $this->getTableFields();
foreach ($tableFields as $fieldName => $dbField) {
if(strcmp($fieldName,$this->getColumnName())===0){
return $dbField->type;
}
}
//This should not be returned if entries in DB are correct.
return null;
}
private function getFieldTypeFromTypeOfData(){
switch($this->fieldType){
case 'T': return "time";
case 'D':
case 'DT': return "date";
case 'E': return "email";
case 'N':
case 'NN': return "double";
case 'P': return "password";
case 'I': return "integer";
case 'V':
default: return "string";
}
}
private function getFieldTypeFromUIType(){
// Cache all the information for futher re-use
if(empty(self::$fieldTypeMapping)) {
$result = $this->pearDB->pquery("select * from vtiger_ws_fieldtype", array());
while($resultrow = $this->pearDB->fetch_array($result)) {
self::$fieldTypeMapping[$resultrow['uitype']] = $resultrow;
}
}
if(isset(WebserviceField::$fieldTypeMapping[$this->getUIType()])){
if(WebserviceField::$fieldTypeMapping[$this->getUIType()] === false){
return null;
}
$row = WebserviceField::$fieldTypeMapping[$this->getUIType()];
return $row['fieldtype'];
} else {
WebserviceField::$fieldTypeMapping[$this->getUIType()] = false;
return null;
}
}
function getPicklistDetails(){
$hardCodedPickListNames = array("hdntaxtype","email_flag");
$hardCodedPickListValues = array(
"hdntaxtype"=>array(
array("label"=>"Individual","value"=>"individual"),
array("label"=>"Group","value"=>"group")
),
"email_flag" => array(
array('label'=>'SAVED','value'=>'SAVED'),
array('label'=>'SENT','value' => 'SENT'),
array('label'=>'MAILSCANNER','value' => 'MAILSCANNER')
)
);
if(in_array(strtolower($this->getFieldName()),$hardCodedPickListNames)){
return $hardCodedPickListValues[strtolower($this->getFieldName())];
}
return $this->getPickListOptions($this->getFieldName());
}
function getPickListOptions(){
$fieldName = $this->getFieldName();
$default_charset = VTWS_PreserveGlobal::getGlobal('default_charset');
$options = array();
$sql = "select * from vtiger_picklist where name=?";
$result = $this->pearDB->pquery($sql,array($fieldName));
$numRows = $this->pearDB->num_rows($result);
if($numRows == 0){
$sql = "select * from vtiger_$fieldName";
$result = $this->pearDB->pquery($sql,array());
$numRows = $this->pearDB->num_rows($result);
for($i=0;$i<$numRows;++$i){
$elem = array();
$picklistValue = $this->pearDB->query_result($result,$i,$fieldName);
$picklistValue = decode_html($picklistValue);
$moduleName = getTabModuleName($this->getTabId());
if($moduleName == 'Events') $moduleName = 'Calendar';
$elem["label"] = getTranslatedString($picklistValue,$moduleName);
$elem["value"] = $picklistValue;
array_push($options,$elem);
}
}else{
$user = VTWS_PreserveGlobal::getGlobal('current_user');
$details = getPickListValues($fieldName,$user->roleid);
for($i=0;$i<sizeof($details);++$i){
$elem = array();
$picklistValue = decode_html($details[$i]);
$moduleName = getTabModuleName($this->getTabId());
if($moduleName == 'Events') $moduleName = 'Calendar';
$elem["label"] = getTranslatedString($picklistValue,$moduleName);
$elem["value"] = $picklistValue;
array_push($options,$elem);
}
}
return $options;
}
function getPresence() {
return $this->presence;
}
}
?>

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.
*
********************************************************************************/
$app_strings = array (
'Groups'=>'Gruppen',
'DocumentFolders'=>'Dokumentenverzeichnisse',
'Currency'=>'Währung',
'SINGLE_Groups'=>'Gruppe',
'SINGLE_DocumentFolders'=>'Dokumentenverzeichnis',
'SINGLE_Currency'=>'Währung',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Ungültige Angabe des alten Passwortes.',
'LBL_NEW_PASSWORD_MISMATCH' => "Die beiden Passwörter stimmen nicht überein.",
'LBL_DATABASE_QUERY_ERROR' => 'Ihre Anfrage konnte aufgrund eines Datenbankfehlers nicht verarbeitet werden.',
'LBL_CHANGE_PASSWORD_FAILURE' => 'Passwort konnte nicht geändert werden.Failed to change password',
);
?>

View File

@ -0,0 +1,26 @@
<?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.
*
********************************************************************************/
$app_strings = array (
'Groups'=>'Groups',
'DocumentFolders'=>'Document Folders',
'Currency'=>'Currency',
'SINGLE_Groups'=>'Group',
'SINGLE_DocumentFolders'=>'Document Folder',
'SINGLE_Currency'=>'Currency',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Invalid value given for old password.',
'LBL_NEW_PASSWORD_MISMATCH' => "New password and confirm password don't match",
'LBL_DATABASE_QUERY_ERROR' => 'Database error while performing requested operation',
'LBL_CHANGE_PASSWORD_FAILURE' => 'Failed to change password',
);
?>

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.
*
********************************************************************************/
$app_strings = array (
'Groups'=>'Groups',
'DocumentFolders'=>'Document Folders',
'Currency'=>'Currency',
'SINGLE_Groups'=>'Group',
'SINGLE_DocumentFolders'=>'Document Folder',
'SINGLE_Currency'=>'Currency',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Invalid value given for old password.',
'LBL_NEW_PASSWORD_MISMATCH' => "New Password and confirm password don't match",
'LBL_DATABASE_QUERY_ERROR' => 'Database error while performing requested operation',
'LBL_CHANGE_PASSWORD_FAILURE' => 'Failed to change password',
);
?>

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.
*
********************************************************************************/
$app_strings = array (
'Groups'=>'Grupos',
'DocumentFolders'=>'Carpetas Documentos',
'Currency'=>'Monedas',
'SINGLE_Groups'=>'Grupo',
'SINGLE_DocumentFolders'=>'Carpeta Documento',
'SINGLE_Currency'=>'Moneda',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Contraseña anterior inválida.',
'LBL_NEW_PASSWORD_MISMATCH' => "Nueva contraseña y confirmación no coinciden.",
'LBL_DATABASE_QUERY_ERROR' => 'Error de base de datos al procesar la operación',
'LBL_CHANGE_PASSWORD_FAILURE' => 'No se ha podido cambiar la contraseña',
);
?>

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.
* Es_mx Author: Francisco Hernandez Odin Consultores www.odin.mx
********************************************************************************/
$app_strings = array (
'Groups'=>'Grupos',
'DocumentFolders'=>'Carpetas Documentos',
'Currency'=>'Monedas',
'SINGLE_Groups'=>'Grupo',
'SINGLE_DocumentFolders'=>'Carpeta Documento',
'SINGLE_Currency'=>'Moneda',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Contraseña anterior inválida.',
'LBL_NEW_PASSWORD_MISMATCH' => "Nueva contraseña y confirmación no coinciden.",
'LBL_DATABASE_QUERY_ERROR' => 'Error de base de datos al procesar la operación',
'LBL_CHANGE_PASSWORD_FAILURE' => 'No se ha podido cambiar la contraseña',
);
?>

View File

@ -0,0 +1,50 @@
<?php
/*******************************************************************************
* The contents of this file are subject to the following licences:
* - SugarCRM Public License Version 1.1.2 http://www.sugarcrm.com/SPL
* - vtiger CRM Public License Version 1.0
* You may not use this file except in compliance with the License
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is: SugarCRM Open Source
* The Initial Developer of the Original Code is SugarCRM, Inc.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.;
* Portions created by vtiger are Copyright (C) vtiger.
* Portions created by Vicus are Copyright (C) Vicus.
* All Rights Reserved.
* Feel free to use / redistribute these languagefiles under the VPL 1.0.
* This translations is based on earlier work of:
* - IT-Online.nl <www.it-online.nl>
* - Weltevree.org <www.Weltevree.org>
********************************************************************************/
/*******************************************************************************
* Vicus eBusiness Solutions Version Control
* @package NL-Dutch
* Description Dutch language pack for vtiger CRM version 5.3.x
* @author $Author: luuk $
* @version $Revision: 1.2 $ $Date: 2011/11/14 17:07:26 $
* @source $Source: /var/lib/cvs/vtiger530/Dutch/include/Webservices/language/nl_nl.lang.php,v $
* @copyright Copyright (c)2005-2011 Vicus eBusiness Solutions bv <info@vicus.nl>
* @license vtiger CRM Public License Version 1.0 (by definition)
********************************************************************************/
$app_strings = array (
'Groups'=>'Groepen',
'DocumentFolders'=>'Documentmappen',
'Currency'=>'Valuta',
'SINGLE_Groups'=>'Groep',
'SINGLE_DocumentFolders'=>'Documentmap',
'SINGLE_Currency'=>'Valuta',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Ongeldige waarden gegeven voor het oude wachtwoord.',
'LBL_NEW_PASSWORD_MISMATCH' => "Het nieuwe wachtwoord komt niet overeen met de bevestiging.",
'LBL_DATABASE_QUERY_ERROR' => 'Database fout tijdens uitvoeren van de gevraagde operatie',
'LBL_CHANGE_PASSWORD_FAILURE' => 'Wijzigen wachtwoord is mislukt',
);
?>

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.
* Contributor(s): Valmir Carlos Trindade/Translate to Brazilian Portuguese|03/03/2012|Curitiba/Paraná/Brasil.|www.ttcasolucoes.com.br
********************************************************************************/
$app_strings = array (
'Groups'=>'Grupos',
'DocumentFolders'=>'Pastas Documentos',
'Currency'=>'Moeda',
'SINGLE_Groups'=>'Grupo',
'SINGLE_DocumentFolders'=>'Pasta Documento',
'SINGLE_Currency'=>'Moeda',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Senha antiga inválida.',
'LBL_NEW_PASSWORD_MISMATCH' => "A nova Senha e a Senha de confirmação não são iguais",
'LBL_DATABASE_QUERY_ERROR' => 'Erro na base de dados ao executar a operação solicitada',
'LBL_CHANGE_PASSWORD_FAILURE' => 'Falha ao alterar a Senha',
);
?>

View File

@ -0,0 +1,40 @@
<?php
/**
* Copyright (C) 2006-2012 YUCHENG HU
*
* ---------------------------------------------------------
* OSSEZ (中国) 信息技术有限公司
* http://www.ossez.com
* http://src.ossez.com
*
* CONTACT
* huyuchengus@gmail.com / yucheng.hu@ossez.com
*
* ---------------------------------------------------------
* [A] GNU GENERAL PUBLIC LICENSE GNU/LGPL
* [B] Apache License, Version 2.0
*
* ---------------------------------------------------------
* NOTE
* 1. 所有的语言配置文件必须采用无 BOM UTF-8 编码
* 2. 本语言文件为 ossez-5.4.0 分支,适用于 vTiger 5.4.0
* ---------------------------------------------------------
*/
$app_strings = array (
'Groups'=>'Groups',
'DocumentFolders'=>'Document Folders',
'Currency'=>'Currency',
'SINGLE_Groups'=>'Group',
'SINGLE_DocumentFolders'=>'Document Folder',
'SINGLE_Currency'=>'Currency',
);
$webservice_strings = array(
'LBL_INVALID_OLD_PASSWORD' => 'Invalid value given for old password.',
'LBL_NEW_PASSWORD_MISMATCH' => "New Password and confirm password don't match",
'LBL_DATABASE_QUERY_ERROR' => 'Database error while performing requested operation',
'LBL_CHANGE_PASSWORD_FAILURE' => 'Failed to change password',
);
?>

View File

@ -0,0 +1,30 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @category Zend
* @package Zend
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Exception extends Exception
{}

91
include/Zend/Json.php Normal file
View File

@ -0,0 +1,91 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Class for encoding to and decoding from JSON.
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Json
{
/**
* How objects should be encoded -- arrays or as StdClass. TYPE_ARRAY is 1
* so that it is a boolean true value, allowing it to be used with
* ext/json's functions.
*/
const TYPE_ARRAY = 1;
const TYPE_OBJECT = 0;
/**
* @var bool
*/
public static $useBuiltinEncoderDecoder = false;
/**
* Decodes the given $encodedValue string which is
* encoded in the JSON format
*
* Uses ext/json's json_decode if available.
*
* @param string $encodedValue Encoded in JSON format
* @param int $objectDecodeType Optional; flag indicating how to decode
* objects. See {@link ZJsonDecoder::decode()} for details.
* @return mixed
*/
public static function decode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
if (function_exists('json_decode') && self::$useBuiltinEncoderDecoder !== true) {
return json_decode($encodedValue, $objectDecodeType);
}
require_once 'include/Zend/Json/Decoder.php';
return Zend_Json_Decoder::decode($encodedValue, $objectDecodeType);
}
/**
* Encode the mixed $valueToEncode into the JSON format
*
* Encodes using ext/json's json_encode() if available.
*
* NOTE: Object should not contain cycles; the JSON format
* does not allow object reference.
*
* NOTE: Only public variables will be encoded
*
* @param mixed $valueToEncode
* @param boolean $cycleCheck Optional; whether or not to check for object recursion; off by default
* @return string JSON encoded object
*/
public static function encode($valueToEncode, $cycleCheck = false)
{
if (function_exists('json_encode') && self::$useBuiltinEncoderDecoder !== true) {
return json_encode($valueToEncode);
}
require_once 'include/Zend/Json/Encoder.php';
return Zend_Json_Encoder::encode($valueToEncode, $cycleCheck);
}
}

View File

@ -0,0 +1,457 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Zend_Json
*/
require_once 'include/Zend/Json.php';
/**
* Zend_Json_Exception
*/
require_once 'include/Zend/Json/Exception.php';
/**
* Decode JSON encoded string to PHP variable constructs
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Json_Decoder
{
/**
* Parse tokens used to decode the JSON object. These are not
* for public consumption, they are just used internally to the
* class.
*/
const EOF = 0;
const DATUM = 1;
const LBRACE = 2;
const LBRACKET = 3;
const RBRACE = 4;
const RBRACKET = 5;
const COMMA = 6;
const COLON = 7;
/**
* Use to maintain a "pointer" to the source being decoded
*
* @var string
*/
protected $_source;
/**
* Caches the source length
*
* @var int
*/
protected $_sourceLength;
/**
* The offset within the souce being decoded
*
* @var int
*
*/
protected $_offset;
/**
* The current token being considered in the parser cycle
*
* @var int
*/
protected $_token;
/**
* Flag indicating how objects should be decoded
*
* @var int
* @access protected
*/
protected $_decodeType;
/**
* Constructor
*
* @param string $source String source to decode
* @param int $decodeType How objects should be decoded -- see
* {@link Zend_Json::TYPE_ARRAY} and {@link Zend_Json::TYPE_OBJECT} for
* valid values
* @return void
*/
protected function __construct($source, $decodeType)
{
// Set defaults
$this->_source = $source;
$this->_sourceLength = strlen($source);
$this->_token = self::EOF;
$this->_offset = 0;
// Normalize and set $decodeType
if (!in_array($decodeType, array(Zend_Json::TYPE_ARRAY, Zend_Json::TYPE_OBJECT)))
{
$decodeType = Zend_Json::TYPE_ARRAY;
}
$this->_decodeType = $decodeType;
// Set pointer at first token
$this->_getNextToken();
}
/**
* Decode a JSON source string
*
* Decodes a JSON encoded string. The value returned will be one of the
* following:
* - integer
* - float
* - boolean
* - null
* - StdClass
* - array
* - array of one or more of the above types
*
* By default, decoded objects will be returned as associative arrays; to
* return a StdClass object instead, pass {@link Zend_Json::TYPE_OBJECT} to
* the $objectDecodeType parameter.
*
* Throws a Zend_Json_Exception if the source string is null.
*
* @static
* @access public
* @param string $source String to be decoded
* @param int $objectDecodeType How objects should be decoded; should be
* either or {@link Zend_Json::TYPE_ARRAY} or
* {@link Zend_Json::TYPE_OBJECT}; defaults to TYPE_ARRAY
* @return mixed
* @throws Zend_Json_Exception
*/
public static function decode($source = null, $objectDecodeType = Zend_Json::TYPE_ARRAY)
{
if (null === $source) {
throw new Zend_Json_Exception('Must specify JSON encoded source for decoding');
} elseif (!is_string($source)) {
throw new Zend_Json_Exception('Can only decode JSON encoded strings');
}
$decoder = new self($source, $objectDecodeType);
return $decoder->_decodeValue();
}
/**
* Recursive driving rountine for supported toplevel tops
*
* @return mixed
*/
protected function _decodeValue()
{
switch ($this->_token) {
case self::DATUM:
$result = $this->_tokenValue;
$this->_getNextToken();
return($result);
break;
case self::LBRACE:
return($this->_decodeObject());
break;
case self::LBRACKET:
return($this->_decodeArray());
break;
default:
return null;
break;
}
}
/**
* Decodes an object of the form:
* { "attribute: value, "attribute2" : value,...}
*
* If ZJsonEnoder or ZJAjax was used to encode the original object
* then a special attribute called __className which specifies a class
* name that should wrap the data contained within the encoded source.
*
* Decodes to either an array or StdClass object, based on the value of
* {@link $_decodeType}. If invalid $_decodeType present, returns as an
* array.
*
* @return array|StdClass
*/
protected function _decodeObject()
{
$members = array();
$tok = $this->_getNextToken();
while ($tok && $tok != self::RBRACE) {
if ($tok != self::DATUM || ! is_string($this->_tokenValue)) {
throw new Zend_Json_Exception('Missing key in object encoding: ' . $this->_source);
}
$key = $this->_tokenValue;
$tok = $this->_getNextToken();
if ($tok != self::COLON) {
throw new Zend_Json_Exception('Missing ":" in object encoding: ' . $this->_source);
}
$tok = $this->_getNextToken();
$members[$key] = $this->_decodeValue();
$tok = $this->_token;
if ($tok == self::RBRACE) {
break;
}
if ($tok != self::COMMA) {
throw new Zend_Json_Exception('Missing "," in object encoding: ' . $this->_source);
}
$tok = $this->_getNextToken();
}
switch ($this->_decodeType) {
case Zend_Json::TYPE_OBJECT:
// Create new StdClass and populate with $members
$result = new StdClass();
foreach ($members as $key => $value) {
$result->$key = $value;
}
break;
case Zend_Json::TYPE_ARRAY:
default:
$result = $members;
break;
}
$this->_getNextToken();
return $result;
}
/**
* Decodes a JSON array format:
* [element, element2,...,elementN]
*
* @return array
*/
protected function _decodeArray()
{
$result = array();
$starttok = $tok = $this->_getNextToken(); // Move past the '['
$index = 0;
while ($tok && $tok != self::RBRACKET) {
$result[$index++] = $this->_decodeValue();
$tok = $this->_token;
if ($tok == self::RBRACKET || !$tok) {
break;
}
if ($tok != self::COMMA) {
throw new Zend_Json_Exception('Missing "," in array encoding: ' . $this->_source);
}
$tok = $this->_getNextToken();
}
$this->_getNextToken();
return($result);
}
/**
* Removes whitepsace characters from the source input
*/
protected function _eatWhitespace()
{
if (preg_match(
'/([\t\b\f\n\r ])*/s',
$this->_source,
$matches,
PREG_OFFSET_CAPTURE,
$this->_offset)
&& $matches[0][1] == $this->_offset)
{
$this->_offset += strlen($matches[0][0]);
}
}
/**
* Retrieves the next token from the source stream
*
* @return int Token constant value specified in class definition
*/
protected function _getNextToken()
{
$this->_token = self::EOF;
$this->_tokenValue = null;
$this->_eatWhitespace();
if ($this->_offset >= $this->_sourceLength) {
return(self::EOF);
}
$str = $this->_source;
$str_length = $this->_sourceLength;
$i = $this->_offset;
$start = $i;
switch ($str{$i}) {
case '{':
$this->_token = self::LBRACE;
break;
case '}':
$this->_token = self::RBRACE;
break;
case '[':
$this->_token = self::LBRACKET;
break;
case ']':
$this->_token = self::RBRACKET;
break;
case ',':
$this->_token = self::COMMA;
break;
case ':':
$this->_token = self::COLON;
break;
case '"':
$result = '';
do {
$i++;
if ($i >= $str_length) {
break;
}
$chr = $str{$i};
if ($chr == '\\') {
$i++;
if ($i >= $str_length) {
break;
}
$chr = $str{$i};
switch ($chr) {
case '"' :
$result .= '"';
break;
case '\\':
$result .= '\\';
break;
case '/' :
$result .= '/';
break;
case 'b' :
$result .= chr(8);
break;
case 'f' :
$result .= chr(12);
break;
case 'n' :
$result .= chr(10);
break;
case 'r' :
$result .= chr(13);
break;
case 't' :
$result .= chr(9);
break;
case '\'' :
$result .= '\'';
break;
default:
throw new Zend_Json_Exception("Illegal escape "
. "sequence '" . $chr . "'");
}
} elseif ($chr == '"') {
break;
} else {
$result .= $chr;
}
} while ($i < $str_length);
$this->_token = self::DATUM;
//$this->_tokenValue = substr($str, $start + 1, $i - $start - 1);
$this->_tokenValue = $result;
break;
case 't':
if (($i+ 3) < $str_length && substr($str, $start, 4) == "true") {
$this->_token = self::DATUM;
}
$this->_tokenValue = true;
$i += 3;
break;
case 'f':
if (($i+ 4) < $str_length && substr($str, $start, 5) == "false") {
$this->_token = self::DATUM;
}
$this->_tokenValue = false;
$i += 4;
break;
case 'n':
if (($i+ 3) < $str_length && substr($str, $start, 4) == "null") {
$this->_token = self::DATUM;
}
$this->_tokenValue = NULL;
$i += 3;
break;
}
if ($this->_token != self::EOF) {
$this->_offset = $i + 1; // Consume the last token character
return($this->_token);
}
$chr = $str{$i};
if ($chr == '-' || $chr == '.' || ($chr >= '0' && $chr <= '9')) {
if (preg_match('/-?([0-9])*(\.[0-9]*)?((e|E)((-|\+)?)[0-9]+)?/s',
$str, $matches, PREG_OFFSET_CAPTURE, $start) && $matches[0][1] == $start) {
$datum = $matches[0][0];
if (is_numeric($datum)) {
if (preg_match('/^0\d+$/', $datum)) {
throw new Zend_Json_Exception("Octal notation not supported by JSON (value: $datum)");
} else {
$val = intval($datum);
$fVal = floatval($datum);
$this->_tokenValue = ($val == $fVal ? $val : $fVal);
}
} else {
throw new Zend_Json_Exception("Illegal number format: $datum");
}
$this->_token = self::DATUM;
$this->_offset = $start + strlen($datum);
}
} else {
throw new Zend_Json_Exception('Illegal Token');
}
return($this->_token);
}
}

View File

@ -0,0 +1,414 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Zend_Json_Exception
*/
require_once 'include/Zend/Json/Exception.php';
/**
* Encode PHP constructs to JSON
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Json_Encoder
{
/**
* Whether or not to check for possible cycling
*
* @var boolean
*/
protected $_cycleCheck;
/**
* Array of visited objects; used to prevent cycling.
*
* @var array
*/
protected $_visited = array();
/**
* Constructor
*
* @param boolean $cycleCheck Whether or not to check for recursion when encoding
* @return void
*/
protected function __construct($cycleCheck = false)
{
$this->_cycleCheck = $cycleCheck;
}
/**
* Use the JSON encoding scheme for the value specified
*
* @param mixed $value The value to be encoded
* @param boolean $cycleCheck Whether or not to check for possible object recursion when encoding
* @return string The encoded value
*/
public static function encode($value, $cycleCheck = false)
{
$encoder = new Zend_Json_Encoder(($cycleCheck) ? true : false);
return $encoder->_encodeValue($value);
}
/**
* Recursive driver which determines the type of value to be encoded
* and then dispatches to the appropriate method. $values are either
* - objects (returns from {@link _encodeObject()})
* - arrays (returns from {@link _encodeArray()})
* - basic datums (e.g. numbers or strings) (returns from {@link _encodeDatum()})
*
* @param $value mixed The value to be encoded
* @return string Encoded value
*/
protected function _encodeValue(&$value)
{
if (is_object($value)) {
return $this->_encodeObject($value);
} else if (is_array($value)) {
return $this->_encodeArray($value);
}
return $this->_encodeDatum($value);
}
/**
* Encode an object to JSON by encoding each of the public properties
*
* A special property is added to the JSON object called '__className'
* that contains the name of the class of $value. This is used to decode
* the object on the client into a specific class.
*
* @param $value object
* @return string
* @throws Zend_Json_Exception If recursive checks are enabled and the object has been serialized previously
*/
protected function _encodeObject(&$value)
{
if ($this->_cycleCheck) {
if ($this->_wasVisited($value)) {
throw new Zend_Json_Exception(
'Cycles not supported in JSON encoding, cycle introduced by '
. 'class "' . get_class($value) . '"'
);
}
$this->_visited[] = $value;
}
$props = '';
foreach (get_object_vars($value) as $name => $propValue) {
if (isset($propValue)) {
$props .= ','
. $this->_encodeValue($name)
. ':'
. $this->_encodeValue($propValue);
}
}
/*return '{"__className":"' . get_class($value) . '"'
. $props . '}';*/
return '{'.substr($props,1).'}';
}
/**
* Determine if an object has been serialized already
*
* @param mixed $value
* @return boolean
*/
protected function _wasVisited(&$value)
{
if (in_array($value, $this->_visited, true)) {
return true;
}
return false;
}
/**
* JSON encode an array value
*
* Recursively encodes each value of an array and returns a JSON encoded
* array string.
*
* Arrays are defined as integer-indexed arrays starting at index 0, where
* the last index is (count($array) -1); any deviation from that is
* considered an associative array, and will be encoded as such.
*
* @param $array array
* @return string
*/
protected function _encodeArray(&$array)
{
$tmpArray = array();
// Check for associative array
if (!empty($array) && (array_keys($array) !== range(0, count($array) - 1))) {
// Associative array
$result = '{';
foreach ($array as $key => $value) {
$key = (string) $key;
$tmpArray[] = $this->_encodeString($key)
. ':'
. $this->_encodeValue($value);
}
$result .= implode(',', $tmpArray);
$result .= '}';
} else {
// Indexed array
$result = '[';
$length = count($array);
for ($i = 0; $i < $length; $i++) {
$tmpArray[] = $this->_encodeValue($array[$i]);
}
$result .= implode(',', $tmpArray);
$result .= ']';
}
return $result;
}
/**
* JSON encode a basic data type (string, number, boolean, null)
*
* If value type is not a string, number, boolean, or null, the string
* 'null' is returned.
*
* @param $value mixed
* @return string
*/
protected function _encodeDatum(&$value)
{
$result = 'null';
if (is_int($value) || is_float($value)) {
$result = (string)$value;
} elseif (is_string($value)) {
$result = $this->_encodeString($value);
} elseif (is_bool($value)) {
$result = $value ? 'true' : 'false';
}
return $result;
}
/**
* JSON encode a string value by escaping characters as necessary
*
* @param $value string
* @return string
*/
protected function _encodeString(&$string)
{
// Escape these characters with a backslash:
// " \ / \n \r \t \b \f
$search = array('\\', "\n", "\t", "\r", "\b", "\f", '"');
$replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"');
$string = str_replace($search, $replace, $string);
// Escape certain ASCII characters:
// 0x08 => \b
// 0x0c => \f
$string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string);
return '"' . $string . '"';
}
/**
* Encode the constants associated with the ReflectionClass
* parameter. The encoding format is based on the class2 format
*
* @param $cls ReflectionClass
* @return string Encoded constant block in class2 format
*/
private static function _encodeConstants(ReflectionClass $cls)
{
$result = "constants : {";
$constants = $cls->getConstants();
$tmpArray = array();
if (!empty($constants)) {
foreach ($constants as $key => $value) {
$tmpArray[] = "$key: " . self::encode($value);
}
$result .= implode(', ', $tmpArray);
}
return $result . "}";
}
/**
* Encode the public methods of the ReflectionClass in the
* class2 format
*
* @param $cls ReflectionClass
* @return string Encoded method fragment
*
*/
private static function _encodeMethods(ReflectionClass $cls)
{
$methods = $cls->getMethods();
$result = 'methods:{';
$started = false;
foreach ($methods as $method) {
if (! $method->isPublic() || !$method->isUserDefined()) {
continue;
}
if ($started) {
$result .= ',';
}
$started = true;
$result .= '' . $method->getName(). ':function(';
if ('__construct' != $method->getName()) {
$parameters = $method->getParameters();
$paramCount = count($parameters);
$argsStarted = false;
$argNames = "var argNames=[";
foreach ($parameters as $param) {
if ($argsStarted) {
$result .= ',';
}
$result .= $param->getName();
if ($argsStarted) {
$argNames .= ',';
}
$argNames .= '"' . $param->getName() . '"';
$argsStarted = true;
}
$argNames .= "];";
$result .= "){"
. $argNames
. 'var result = ZAjaxEngine.invokeRemoteMethod('
. "this, '" . $method->getName()
. "',argNames,arguments);"
. 'return(result);}';
} else {
$result .= "){}";
}
}
return $result . "}";
}
/**
* Encode the public properties of the ReflectionClass in the class2
* format.
*
* @param $cls ReflectionClass
* @return string Encode properties list
*
*/
private static function _encodeVariables(ReflectionClass $cls)
{
$properties = $cls->getProperties();
$propValues = get_class_vars($cls->getName());
$result = "variables:{";
$cnt = 0;
$tmpArray = array();
foreach ($properties as $prop) {
if (! $prop->isPublic()) {
continue;
}
$tmpArray[] = $prop->getName()
. ':'
. self::encode($propValues[$prop->getName()]);
}
$result .= implode(',', $tmpArray);
return $result . "}";
}
/**
* Encodes the given $className into the class2 model of encoding PHP
* classes into JavaScript class2 classes.
* NOTE: Currently only public methods and variables are proxied onto
* the client machine
*
* @param $className string The name of the class, the class must be
* instantiable using a null constructor
* @param $package string Optional package name appended to JavaScript
* proxy class name
* @return string The class2 (JavaScript) encoding of the class
* @throws Zend_Json_Exception
*/
public static function encodeClass($className, $package = '')
{
$cls = new ReflectionClass($className);
if (! $cls->isInstantiable()) {
throw new Zend_Json_Exception("$className must be instantiable");
}
return "Class.create('$package$className',{"
. self::_encodeConstants($cls) .","
. self::_encodeMethods($cls) .","
. self::_encodeVariables($cls) .'});';
}
/**
* Encode several classes at once
*
* Returns JSON encoded classes, using {@link encodeClass()}.
*
* @param array $classNames
* @param string $package
* @return string
*/
public static function encodeClasses(array $classNames, $package = '')
{
$result = '';
foreach ($classNames as $className) {
$result .= self::encodeClass($className, $package);
}
return $result;
}
}

View File

@ -0,0 +1,36 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Zend_Exception
*/
require_once 'include/Zend/Exception.php';
/**
* @category Zend
* @package Zend_Json
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Json_Exception extends Zend_Exception
{}

View File

@ -0,0 +1 @@
* Unit tests

View File

@ -0,0 +1,158 @@
<?php
CharStreamConst::$EOF = -1;
class ANTLRStringStream implements CharStream {
/** Copy data in string to a local char array */
public function __construct($input) {
$this->p=0;
$this->line = 1;
$this->charPositionInLine = 0;
$this->markDepth = 0;
$this->markers = null;
$this->lastMarker=0;
$this->name=null;
$this->data = strToIntArray($input);
$this->n = strlen($input);
}
/** Reset the stream so that it's in the same state it was
* when the object was created *except* the data array is not
* touched.
*/
public function reset() {
$this->p = 0;
$this->line = 1;
$this->charPositionInLine = 0;
$this->markDepth = 0;
}
public function consume() {
if ( $this->p < $this->n ) {
$this->charPositionInLine++;
if ( $this->data[$this->p]==ord("\n") ) {
$this->line++;
$this->charPositionInLine=0;
}
$this->p++;
}
}
public function LA($i) {
if ( $i==0 ) {
return 0; // undefined
}
if ( $i<0 ) {
$i++; // e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
if ( ($this->p+$i-1) < 0 ) {
return CharStreamConst::$EOF; // invalid; no char before first char
}
}
if ( ($this->p+$i-1) >= $this->n ) {
//System.out.println("char LA("+i+")=EOF; p="+p);
return CharStreamConst::$EOF;
}
//System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p);
//System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length);
return $this->data[$this->p+$i-1];
}
public function LT($i) {
return $this->LA($i);
}
/** Return the current input symbol index 0..n where n indicates the
* last symbol has been read. The index is the index of char to
* be returned from LA(1).
*/
public function index() {
return $this->p;
}
public function size() {
return $this->n;
}
public function mark() {
if ( $this->markers == null) {
$this->markers = array();
$this->markers[] = null; // depth 0 means no backtracking, leave blank
}
$this->markDepth++;
$state = null;
if ($this->markDepth>=sizeof($this->markers)) {
$state = new CharStreamState();
$this->markers[] = $state;
}
else {
$state = $this->markers[$this->markDepth];
}
$state->p = $this->p;
$state->line = $this->line;
$state->charPositionInLine = $this->charPositionInLine;
$this->lastMarker = $this->markDepth;
return $this->markDepth;
}
public function rewind($m=null) {
if($m===null){
$this->rewind((int)$this->lastMarker);
}else{
$state = $this->markers[$m];
// restore stream state
$this->seek($state->p);
$this->line = $state->line;
$this->charPositionInLine = $state->charPositionInLine;
$this->release($m);
}
}
public function release($marker) {
// unwind any other markers made after m and release m
$this->markDepth = $marker;
// release this marker
$this->markDepth--;
}
/** consume() ahead until p==index; can't just set p=index as we must
* update line and charPositionInLine.
*/
public function seek($index) {
if ( $index<=$this->p ) {
$this->p = $index; // just jump; don't update stream state (line, ...)
return;
}
// seek forward, consume until p hits index
while ( $this->p<$index ) {
$this->consume();
}
}
public function substring($start, $stop) {
return implode(array_map('chr', array_slice($this->data, $start, $stop-$start+1)));
}
public function getLine() {
return $this->line;
}
public function getCharPositionInLine() {
return $this->charPositionInLine;
}
public function setLine($line) {
$this->line = $line;
}
public function setCharPositionInLine($pos) {
$this->charPositionInLine = $pos;
}
public function getSourceName() {
return $this->name;
}
}
?>

View File

@ -0,0 +1,299 @@
<?php
/**
* Base class for lexers
*/
abstract class AntlrLexer extends BaseRecognizer{
public static $DEFAULT_TOKEN_CHANNEL = 0;
protected $input;
public function __construct($input, $state=null) {
if($state==null){
$state = new RecognizerSharedState();
}
$this->state = $state;
$this->input = $input;
}
public function reset() {
parent::reset(); // reset all recognizer state variables
// wack Lexer state variables
if ( $this->input!=null ) {
$this->input->seek(0); // rewind the input
}
if ( $this->state==null ) {
return; // no shared state work to do
}
$this->state->token = null;
$this->state->type = TokenConst::$INVALID_TOKEN_TYPE;
$this->state->channel = TokenConst::$DEFAULT_CHANNEL;
$this->state->tokenStartCharIndex = -1;
$this->state->tokenStartCharPositionInLine = -1;
$this->state->tokenStartLine = -1;
$this->state->text = null;
}
/** Return a token from this source; i.e., match a token on the char
* stream.
*/
public function nextToken() {
while (true) {
$this->state->token = null;
$this->state->channel = 0;//Token::DEFAULT_CHANNEL;
$this->state->tokenStartCharIndex = $this->input->index();
$this->state->tokenStartCharPositionInLine = $this->input->getCharPositionInLine();
$this->state->tokenStartLine = $this->input->getLine();
$this->state->text = null;
if ( $this->input->LA(1)==CharStreamConst::$EOF ) {
return TokenConst::$EOF_TOKEN;
}
try {
$this->mTokens();
if ( $this->state->token==null ) {
$this->emit();
}
else if ( $this->state->token==Token::$SKIP_TOKEN ) {
continue;
}
return $this->state->token;
}
catch (NoViableAltException $nva) {
$this->reportError($nva);
$this->recover($nva); // throw out current char and try again
}
catch (RecognitionException $re) {
$this->reportError($re);
// match() routine has already called recover()
}
}
}
/** Instruct the lexer to skip creating a token for current lexer rule
* and look for another token. nextToken() knows to keep looking when
* a lexer rule finishes with token set to SKIP_TOKEN. Recall that
* if token==null at end of any token rule, it creates one for you
* and emits it.
*/
public function skip() {
$this->state->token = TokenConst::$SKIP_TOKEN;
}
/** This is the lexer entry point that sets instance var 'token' */
public abstract function mTokens();
/** Set the char stream and reset the lexer */
public function setCharStream($input) {
$this->input = null;
$this->reset();
$this->input = $input;
}
public function getCharStream() {
return $this->input;
}
public function getSourceName() {
return $this->input->getSourceName();
}
/** Currently does not support multiple emits per nextToken invocation
* for efficiency reasons. Subclass and override this method and
* nextToken (to push tokens into a list and pull from that list rather
* than a single variable as this implementation does).
*/
/** The standard method called to automatically emit a token at the
* outermost lexical rule. The token object should point into the
* char buffer start..stop. If there is a text override in 'text',
* use that to set the token's text. Override this method to emit
* custom Token objects.
*
* If you are building trees, then you should also override
* Parser or TreeParser.getMissingSymbol().
*/
public function emit($token=null) {
if($token==null){
$token = CommonToken::forInput($this->input, $this->state->type, $this->state->channel,
$this->state->tokenStartCharIndex, $this->getCharIndex()-1);
$token->setLine($this->state->tokenStartLine);
$token->setText($this->state->text);
$token->setCharPositionInLine($this->state->tokenStartCharPositionInLine);
}
$this->state->token = $token;
return $token;
}
function matchString($s){
$i = 0;
while ( $i<strlen($s)) {
if ( $this->input->LA(1)!=charAt($s, $i) ) {
if ( $this->state->backtracking>0 ) {
$this->state->failed = true;
return;
}
$mte = new MismatchedTokenException(charAt($s, $i), $this->input);
$this->recover($mte);
throw $mte;
}
$i++;
$this->input->consume();
$state->failed = false;
}
}
public function matchAny() {
$this->input->consume();
}
public function matchChar($c) {
if ($this->input->LA(1)!=$c ) {
if ( $this->state->backtracking>0 ) {
$this->state->failed = true;
return;
}
$mte = new MismatchedTokenException($c, $this->input);
$this->recover($mte); // don't really recover; just consume in lexer
throw $mte;
}
$this->input->consume();
$this->state->failed = false;
}
public function matchRange($a, $b) {
if ( $this->input->LA(1)<$a || $this->input->LA(1)>$b ) {
if ( $this->state->backtracking>0 ) {
$this->state->failed = true;
return;
}
$mre = new MismatchedRangeException($a, $b, $this->input);
$this->recover($mre);
throw $mre;
}
$this->input->consume();
$this->state->failed = false;
}
public function getLine() {
return $this->input->getLine();
}
public function getCharPositionInLine() {
return $this->input->getCharPositionInLine();
}
/** What is the index of the current character of lookahead? */
public function getCharIndex() {
return $this->input->index();
}
/** Return the text matched so far for the current token or any
* text override.
*/
public function getText() {
if ( $this->state->text!=null ) {
return $this->state->text;
}
return $this->input->substring($this->state->tokenStartCharIndex,$this->getCharIndex()-1);
}
/** Set the complete text of this token; it wipes any previous
* changes to the text.
*/
public function setText($text) {
$this->state->text = $text;
}
public function reportError($e) {
/** TODO: not thought about recovery in lexer yet.
*
// if we've already reported an error and have not matched a token
// yet successfully, don't report any errors.
if ( errorRecovery ) {
//System.err.print("[SPURIOUS] ");
return;
}
errorRecovery = true;
*/
$this->displayRecognitionError($this->getTokenNames(), $e);
}
public function getErrorMessage($e, $tokenNames) {
$msg = null;
if ( $e instanceof MismatchedTokenException ) {
$mte = $e;
$msg = "mismatched character ".$this->getCharErrorDisplay($e->c).
" expecting ".$this->getCharErrorDisplay($mte->expecting);
}
else if ( $e instanceof NoViableAltException ) {
$nvae = $e;
// for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>"
// and "(decision="+nvae.decisionNumber+") and
// "state "+nvae.stateNumber
$msg = "no viable alternative at character ".$this->getCharErrorDisplay($e->c);
}
else if ( $e instanceof EarlyExitException ) {
$eee = $e;
// for development, can add "(decision="+eee.decisionNumber+")"
$msg = "required (...)+ loop did not match anything at character ".$this->getCharErrorDisplay($e->c);
}
else if ( $e instanceof MismatchedNotSetException ) {
$mse = $e;
$msg = "mismatched character ".$this->getCharErrorDisplay($e->c)." expecting set ".$mse->expecting;
}
else if ( $e instanceof MismatchedSetException ) {
$mse = $e;
$msg = "mismatched character ".$this->getCharErrorDisplay($e->c)." expecting set ".$mse->expecting;
}
else if ( $e instanceof MismatchedRangeException ) {
$mre = $e;
$msg = "mismatched character ".$this->getCharErrorDisplay($e->c)." expecting set ".
$this->getCharErrorDisplay($mre->a)."..".$this->getCharErrorDisplay($mre->b);
}
else {
$msg = parent::getErrorMessage($e, $tokenNames);
}
return $msg;
}
public function getCharErrorDisplay($c) {
$s = chr($c);
switch ( $s ) {
case '\n' :
$s = "\\n";
break;
case '\t' :
$s = "\\t";
break;
case '\r' :
$s = "\\r";
break;
}
if ($c==TokenConst::$EOF){
$s = "<EOF>";
}
return "'".$s."'";
}
/** Lexers can normally match any char in it's vocabulary after matching
* a token, so do the easy thing and just kill a character and hope
* it all works out. You can instead use the rule invocation stack
* to do sophisticated error recovery if you are in a fragment rule.
*/
public function recover($re) {
$this->input->consume();
}
public function traceIn($ruleName, $ruleIndex) {
$inputSymbol = $this->input->LT(1)." line=".$this->getLine().":".$this->getCharPositionInLine();
parent::traceIn($ruleName, $ruleIndex, $inputSymbol);
}
public function traceOut($ruleName, $ruleIndex) {
$inputSymbol = $this->input->LT(1)." line=".$this->getLine().":".$this->getCharPositionInLine();
parent::traceOut($ruleName, $ruleIndex, $inputSymbol);
}
}
?>

View File

@ -0,0 +1,100 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** A parser for TokenStreams. "parser grammars" result in a subclass
* of this.
*/
class AntlrParser extends BaseRecognizer {
public $input;
public function __construct($input, $state = null) {
parent::__construct($state); // share the state object with another parser
$this->setTokenStream($input);
}
public function reset() {
parent::reset(); // reset all recognizer state variables
if ( $this->input!=null ) {
$this->input->seek(0); // rewind the input
}
}
protected function getCurrentInputSymbol($input) {
return $this->input->LT(1);
}
protected function getMissingSymbol($input, $e, $expectedTokenType, $follow)
{
$tokenText = null;
if ( $expectedTokenType==TokenConst::$EOF ){
$tokenText = "<missing EOF>";
} else {
$tokenNames = $this->getTokenNames();
$tokenText = "<missing ".$tokenNames[$expectedTokenType].">";
}
$t = CommonToken::forTypeAndText($expectedTokenType, $tokenText);
$current = $input->LT(1);
if ( $current->getType() == TokenConst::$EOF ) {
$current = $this->input->LT(-1);
}
$t->line = $current->getLine();
$t->charPositionInLine = $current->getCharPositionInLine();
$t->channel = $DEFAULT_TOKEN_CHANNEL;
return $t;
}
/** Set the token stream and reset the parser */
public function setTokenStream($input) {
$this->input = null;
$this->reset();
$this->input = $input;
}
public function getTokenStream() {
return $this->input;
}
public function getSourceName() {
return $this->input->getSourceName();
}
public function traceIn($ruleName, $ruleIndex) {
parent::traceIn($ruleName, $ruleIndex, $this->input->LT(1));
}
public function traceOut($ruleName, $ruleIndex) {
parent::traceOut($ruleName, $ruleIndex, $this->input->LT(1));
}
}
?>

View File

@ -0,0 +1,851 @@
<?php
abstract class BaseRecognizer{
public static $MEMO_RULE_FAILED = -2;
public static $MEMO_RULE_UNKNOWN = -1;
public static $INITIAL_FOLLOW_STACK_SIZE = 100;
// copies from Token object for convenience in actions
public static $DEFAULT_TOKEN_CHANNEL; //= TokenConst::$DEFAULT_CHANNEL;
public static $HIDDEN; //= TokenConst::$HIDDEN_CHANNEL;
public static $NEXT_TOKEN_RULE_NAME = "nextToken";
public function __construct($state = null) {
if ( $state==null ) {
$state = new RecognizerSharedState();
}
$this->state = $state;
}
/** reset the parser's state; subclasses must rewinds the input stream */
public function reset() {
// wack everything related to error recovery
if ( $this->state==null ) {
return; // no shared state work to do
}
$this->state->_fsp = -1;
$this->state->errorRecovery = false;
$this->state->lastErrorIndex = -1;
$this->state->failed = false;
$this->state->syntaxErrors = 0;
// wack everything related to backtracking and memoization
$this->state->backtracking = 0;
for ($i = 0; $this->state->ruleMemo!=null && $i < $this->state->ruleMemo->length; $i++) { // wipe cache
$this->state->ruleMemo[$i] = null;
}
}
/** Match current input symbol against ttype. Attempt
* single token insertion or deletion error recovery. If
* that fails, throw MismatchedTokenException.
*
* To turn off single token insertion or deletion error
* recovery, override mismatchRecover() and have it call
* plain mismatch(), which does not recover. Then any error
* in a rule will cause an exception and immediate exit from
* rule. Rule would recover by resynchronizing to the set of
* symbols that can follow rule ref.
*/
public function match($input, $ttype, $follow)
{
//System.out.println("match "+((TokenStream)input).LT(1));
$matchedSymbol = $this->getCurrentInputSymbol($input);
if ( $input->LA(1)==$ttype ) {
$input->consume();
$this->state->errorRecovery = false;
$this->state->failed = false;
return $matchedSymbol;
}
if ( $this->state->backtracking>0 ) {
$this->state->failed = true;
return $matchedSymbol;
}
$matchedSymbol = $this->recoverFromMismatchedToken($input, $ttype, $follow);
return $matchedSymbol;
}
/** Match the wildcard: in a symbol */
public function matchAny($input) {
$this->state->errorRecovery = false;
$this->state->failed = false;
$input->consume();
}
public function mismatchIsUnwantedToken($input, $ttype) {
return $input->LA(2)==$ttype;
}
public function mismatchIsMissingToken($input, $follow) {
if ( $follow==null ) {
// we have no information about the follow; we can only consume
// a single token and hope for the best
return $false;
}
// compute what can follow this grammar element reference
if ( $follow->member(TokenConst::$EOR_TOKEN_TYPE) ) {
$viableTokensFollowingThisRule = $this->computeContextSensitiveRuleFOLLOW();
$follow = $follow->union($viableTokensFollowingThisRule);
if ( $this->state->_fsp>=0 ) { // remove EOR if we're not the start symbol
$follow->remove(TokenConst::$EOR_TOKEN_TYPE);
}
}
// if current token is consistent with what could come after set
// then we know we're missing a token; error recovery is free to
// "insert" the missing token
//System.out.println("viable tokens="+follow.toString(getTokenNames()));
//System.out.println("LT(1)="+((TokenStream)input).LT(1));
// BitSet cannot handle negative numbers like -1 (EOF) so I leave EOR
// in follow set to indicate that the fall of the start symbol is
// in the set (EOF can follow).
if ( $follow->member($input->LA(1)) || $follow->member(TokenConst::$EOR_TOKEN_TYPE) ) {
//System.out.println("LT(1)=="+((TokenStream)input).LT(1)+" is consistent with what follows; inserting...");
return true;
}
return false;
}
/** Factor out what to do upon token mismatch so tree parsers can behave
* differently. Override and call mismatchRecover(input, ttype, follow)
* to get single token insertion and deletion. Use this to turn of
* single token insertion and deletion. Override mismatchRecover
* to call this instead.
*/
protected function mismatch($input, $ttype, $follow)
{
if ( $this->mismatchIsUnwantedToken($input, $ttype) ) {
throw new UnwantedTokenException($ttype, $input);
}
else if ( $this->mismatchIsMissingToken($input, $follow) ) {
throw new MissingTokenException($ttype, $input, null);
}
throw new MismatchedTokenException($ttype, $input);
}
/** Report a recognition problem.
*
* This method sets errorRecovery to indicate the parser is recovering
* not parsing. Once in recovery mode, no errors are generated.
* To get out of recovery mode, the parser must successfully match
* a token (after a resync). So it will go:
*
* 1. error occurs
* 2. enter recovery mode, report error
* 3. consume until token found in resynch set
* 4. try to resume parsing
* 5. next match() will reset errorRecovery mode
*
* If you override, make sure to update syntaxErrors if you care about that.
*/
public function reportError($e) {
// if we've already reported an error and have not matched a token
// yet successfully, don't report any errors.
if ( $this->state->errorRecovery ) {
//System.err.print("[SPURIOUS] ");
return;
}
$this->state->syntaxErrors++; // don't count spurious
$this->state->errorRecovery = true;
$this->displayRecognitionError($this->getTokenNames(), $e);
}
public function displayRecognitionError($tokenNames, $e){
$hdr = $this->getErrorHeader($e);
$msg = $this->getErrorMessage($e, $tokenNames);
$this->emitErrorMessage($hdr." ".$msg);
}
/** What error message should be generated for the various
* exception types?
*
* Not very object-oriented code, but I like having all error message
* generation within one method rather than spread among all of the
* exception classes. This also makes it much easier for the exception
* handling because the exception classes do not have to have pointers back
* to this object to access utility routines and so on. Also, changing
* the message for an exception type would be difficult because you
* would have to subclassing exception, but then somehow get ANTLR
* to make those kinds of exception objects instead of the default.
* This looks weird, but trust me--it makes the most sense in terms
* of flexibility.
*
* For grammar debugging, you will want to override this to add
* more information such as the stack frame with
* getRuleInvocationStack(e, this.getClass().getName()) and,
* for no viable alts, the decision description and state etc...
*
* Override this to change the message generated for one or more
* exception types.
*/
public function getErrorMessage($e, $tokenNames) {
$msg = $e->getMessage();
if ( $e instanceof UnwantedTokenException ) {
$ute = $e;
$tokenName="<unknown>";
if ( $ute->expecting== TokenConst::$EOF ) {
$tokenName = "EOF";
}
else {
$tokenName = $tokenNames[$ute->expecting];
}
$msg = "extraneous input ".$this->getTokenErrorDisplay($ute->getUnexpectedToken()).
" expecting ".$tokenName;
}
else if ( $e instanceof MissingTokenException ) {
$mte = $e;
$tokenName="<unknown>";
if ( $mte->expecting== TokenConst::$EOF ) {
$tokenName = "EOF";
}
else {
$tokenName = $tokenNames[$mte->expecting];
}
$msg = "missing ".$tokenName." at ".$this->getTokenErrorDisplay($e->token);
}
else if ( $e instanceof MismatchedTokenException ) {
$mte = $e;
$tokenName="<unknown>";
if ( $mte->expecting== TokenConst::$EOF ) {
$tokenName = "EOF";
}
else {
$tokenName = $tokenNames[$mte->expecting];
}
$msg = "mismatched input ".$this->getTokenErrorDisplay($e->token).
" expecting ".$tokenName;
}
else if ( $e instanceof MismatchedTreeNodeException ) {
$mtne = $e;
$tokenName="<unknown>";
if ( $mtne->expecting==TokenConst::$EOF ) {
$tokenName = "EOF";
}
else {
$tokenName = $tokenNames[$mtne->expecting];
}
$msg = "mismatched tree node: ".$mtne->node.
" expecting ".$tokenName;
}
else if ( $e instanceof NoViableAltException ) {
$nvae = $e;
// for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>"
// and "(decision="+nvae.decisionNumber+") and
// "state "+nvae.stateNumber
$msg = "no viable alternative at input ".$this->getTokenErrorDisplay($e->token);
}
else if ( $e instanceof EarlyExitException ) {
$eee = $e;
// for development, can add "(decision="+eee.decisionNumber+")"
$msg = "required (...)+ loop did not match anything at input ".
getTokenErrorDisplay($e->token);
}
else if ( $e instanceof MismatchedSetException ) {
$mse = $e;
$msg = "mismatched input ".$this->getTokenErrorDisplay($e->token).
" expecting set ".$mse->expecting;
}
else if ( $e instanceof MismatchedNotSetException ) {
$mse = $e;
$msg = "mismatched input ".$this->getTokenErrorDisplay($e->token).
" expecting set ".$mse->expecting;
}
else if ( $e instanceof FailedPredicateException ) {
$fpe = $e;
$msg = "rule ".$fpe->ruleName." failed predicate: {".
$fpe->predicateText."}?";
}
return $msg;
}
/** Get number of recognition errors (lexer, parser, tree parser). Each
* recognizer tracks its own number. So parser and lexer each have
* separate count. Does not count the spurious errors found between
* an error and next valid token match
*
* See also reportError()
*/
public function getNumberOfSyntaxErrors() {
return $state->syntaxErrors;
}
/** What is the error header, normally line/character position information? */
public function getErrorHeader($e) {
return "line ".$e->line.":".$e->charPositionInLine;
}
/** How should a token be displayed in an error message? The default
* is to display just the text, but during development you might
* want to have a lot of information spit out. Override in that case
* to use t.toString() (which, for CommonToken, dumps everything about
* the token). This is better than forcing you to override a method in
* your token objects because you don't have to go modify your lexer
* so that it creates a new Java type.
*/
public function getTokenErrorDisplay($t) {
$s = $t->getText();
if ( $s==null ) {
if ( $t->getType()==TokenConst::$EOF ) {
$s = "<EOF>";
}
else {
$s = "<".$t->getType().">";
}
}
$s = str_replace("\n", '\n', $s);
$s = str_replace("\r",'\r', $s);
$s = str_replace("\t",'\t', $s);
return "'".$s."'";
}
/** Override this method to change where error messages go */
public function emitErrorMessage($msg) {
echo $msg;
}
/** Recover from an error found on the input stream. This is
* for NoViableAlt and mismatched symbol exceptions. If you enable
* single token insertion and deletion, this will usually not
* handle mismatched symbol exceptions but there could be a mismatched
* token that the match() routine could not recover from.
*/
public function recover($input, $re) {
if ( $this->state->lastErrorIndex==$input->index() ) {
// uh oh, another error at same token index; must be a case
// where LT(1) is in the recovery token set so nothing is
// consumed; consume a single token so at least to prevent
// an infinite loop; this is a failsafe.
$input->consume();
}
$this->state->lastErrorIndex = $input->index();
$followSet = $this->computeErrorRecoverySet();
$this->beginResync();
$this->consumeUntilInSet($input, $followSet);
$this->endResync();
}
/** A hook to listen in on the token consumption during error recovery.
* The DebugParser subclasses this to fire events to the listenter.
*/
public function beginResync() {
}
public function endResync() {
}
/* Compute the error recovery set for the current rule. During
* rule invocation, the parser pushes the set of tokens that can
* follow that rule reference on the stack; this amounts to
* computing FIRST of what follows the rule reference in the
* enclosing rule. This local follow set only includes tokens
* from within the rule; i.e., the FIRST computation done by
* ANTLR stops at the end of a rule.
*
* EXAMPLE
*
* When you find a "no viable alt exception", the input is not
* consistent with any of the alternatives for rule r. The best
* thing to do is to consume tokens until you see something that
* can legally follow a call to r *or* any rule that called r.
* You don't want the exact set of viable next tokens because the
* input might just be missing a token--you might consume the
* rest of the input looking for one of the missing tokens.
*
* Consider grammar:
*
* a : '[' b ']'
* | '(' b ')'
* ;
* b : c '^' INT ;
* c : ID
* | INT
* ;
*
* At each rule invocation, the set of tokens that could follow
* that rule is pushed on a stack. Here are the various "local"
* follow sets:
*
* FOLLOW(b1_in_a) = FIRST(']') = ']'
* FOLLOW(b2_in_a) = FIRST(')') = ')'
* FOLLOW(c_in_b) = FIRST('^') = '^'
*
* Upon erroneous input "[]", the call chain is
*
* a -> b -> c
*
* and, hence, the follow context stack is:
*
* depth local follow set after call to rule
* 0 <EOF> a (from main())
* 1 ']' b
* 3 '^' c
*
* Notice that ')' is not included, because b would have to have
* been called from a different context in rule a for ')' to be
* included.
*
* For error recovery, we cannot consider FOLLOW(c)
* (context-sensitive or otherwise). We need the combined set of
* all context-sensitive FOLLOW sets--the set of all tokens that
* could follow any reference in the call chain. We need to
* resync to one of those tokens. Note that FOLLOW(c)='^' and if
* we resync'd to that token, we'd consume until EOF. We need to
* sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.
* In this case, for input "[]", LA(1) is in this set so we would
* not consume anything and after printing an error rule c would
* return normally. It would not find the required '^' though.
* At this point, it gets a mismatched token error and throws an
* exception (since LA(1) is not in the viable following token
* set). The rule exception handler tries to recover, but finds
* the same recovery set and doesn't consume anything. Rule b
* exits normally returning to rule a. Now it finds the ']' (and
* with the successful match exits errorRecovery mode).
*
* So, you cna see that the parser walks up call chain looking
* for the token that was a member of the recovery set.
*
* Errors are not generated in errorRecovery mode.
*
* ANTLR's error recovery mechanism is based upon original ideas:
*
* "Algorithms + Data Structures = Programs" by Niklaus Wirth
*
* and
*
* "A note on error recovery in recursive descent parsers":
* http://portal.acm.org/citation.cfm?id=947902.947905
*
* Later, Josef Grosch had some good ideas:
*
* "Efficient and Comfortable Error Recovery in Recursive Descent
* Parsers":
* ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip
*
* Like Grosch I implemented local FOLLOW sets that are combined
* at run-time upon error to avoid overhead during parsing.
*/
protected function computeErrorRecoverySet() {
return $this->combineFollows(false);
}
/** Compute the context-sensitive FOLLOW set for current rule.
* This is set of token types that can follow a specific rule
* reference given a specific call chain. You get the set of
* viable tokens that can possibly come next (lookahead depth 1)
* given the current call chain. Contrast this with the
* definition of plain FOLLOW for rule r:
*
* FOLLOW(r)={x | S=>*alpha r beta in G and x in FIRST(beta)}
*
* where x in T* and alpha, beta in V*; T is set of terminals and
* V is the set of terminals and nonterminals. In other words,
* FOLLOW(r) is the set of all tokens that can possibly follow
* references to r in *any* sentential form (context). At
* runtime, however, we know precisely which context applies as
* we have the call chain. We may compute the exact (rather
* than covering superset) set of following tokens.
*
* For example, consider grammar:
*
* stat : ID '=' expr ';' // FOLLOW(stat)=={EOF}
* | "return" expr '.'
* ;
* expr : atom ('+' atom)* ; // FOLLOW(expr)=={';','.',')'}
* atom : INT // FOLLOW(atom)=={'+',')',';','.'}
* | '(' expr ')'
* ;
*
* The FOLLOW sets are all inclusive whereas context-sensitive
* FOLLOW sets are precisely what could follow a rule reference.
* For input input "i=(3);", here is the derivation:
*
* stat => ID '=' expr ';'
* => ID '=' atom ('+' atom)* ';'
* => ID '=' '(' expr ')' ('+' atom)* ';'
* => ID '=' '(' atom ')' ('+' atom)* ';'
* => ID '=' '(' INT ')' ('+' atom)* ';'
* => ID '=' '(' INT ')' ';'
*
* At the "3" token, you'd have a call chain of
*
* stat -> expr -> atom -> expr -> atom
*
* What can follow that specific nested ref to atom? Exactly ')'
* as you can see by looking at the derivation of this specific
* input. Contrast this with the FOLLOW(atom)={'+',')',';','.'}.
*
* You want the exact viable token set when recovering from a
* token mismatch. Upon token mismatch, if LA(1) is member of
* the viable next token set, then you know there is most likely
* a missing token in the input stream. "Insert" one by just not
* throwing an exception.
*/
protected function computeContextSensitiveRuleFOLLOW() {
return $this->combineFollows(true);
}
protected function combineFollows($exact) {
$top = $this->state->_fsp;
$followSet = new Set(array());
for ($i=$top; $i>=0; $i--) {
$localFollowSet = $this->state->following[$i];
/*
System.out.println("local follow depth "+i+"="+
localFollowSet.toString(getTokenNames())+")");
*/
$followSet->unionInPlace($localFollowSet);
if ( $this->exact ) {
// can we see end of rule?
if ( $localFollowSet->member(TokenConst::$EOR_TOKEN_TYPE) ) {
// Only leave EOR in set if at top (start rule); this lets
// us know if have to include follow(start rule); i.e., EOF
if ( $i>0 ) {
$followSet->remove(TokenConst::$EOR_TOKEN_TYPE);
}
}
else { // can't see end of rule, quit
break;
}
}
}
return $followSet;
}
/** Attempt to recover from a single missing or extra token.
*
* EXTRA TOKEN
*
* LA(1) is not what we are looking for. If LA(2) has the right token,
* however, then assume LA(1) is some extra spurious token. Delete it
* and LA(2) as if we were doing a normal match(), which advances the
* input.
*
* MISSING TOKEN
*
* If current token is consistent with what could come after
* ttype then it is ok to "insert" the missing token, else throw
* exception For example, Input "i=(3;" is clearly missing the
* ')'. When the parser returns from the nested call to expr, it
* will have call chain:
*
* stat -> expr -> atom
*
* and it will be trying to match the ')' at this point in the
* derivation:
*
* => ID '=' '(' INT ')' ('+' atom)* ';'
* ^
* match() will see that ';' doesn't match ')' and report a
* mismatched token error. To recover, it sees that LA(1)==';'
* is in the set of tokens that can follow the ')' token
* reference in rule atom. It can assume that you forgot the ')'.
*/
protected function recoverFromMismatchedToken($input, $ttype, $follow)
{
$e = null;
// if next token is what we are looking for then "delete" this token
if ( $this->mismatchIsUnwantedToken($input, $ttype) ) {
$e = new UnwantedTokenException($ttype, $input);
/*
System.err.println("recoverFromMismatchedToken deleting "+
((TokenStream)input).LT(1)+
" since "+((TokenStream)input).LT(2)+" is what we want");
*/
$this->beginResync();
$input->consume(); // simply delete extra token
$this->endResync();
$this->reportError($e); // report after consuming so AW sees the token in the exception
// we want to return the token we're actually matching
$matchedSymbol = $this->getCurrentInputSymbol($input);
$input->consume(); // move past ttype token as if all were ok
return $matchedSymbol;
}
// can't recover with single token deletion, try insertion
if ( $this->mismatchIsMissingToken($input, $follow) ) {
$inserted = $this->getMissingSymbol($input, $e, $ttype, $follow);
$e = new MissingTokenException($ttype, $input, $inserted);
$this->reportError($e); // report after inserting so AW sees the token in the exception
return $inserted;
}
// even that didn't work; must throw the exception
$e = new MismatchedTokenException($ttype, $input);
throw $e;
}
/** Not currently used */
public function recoverFromMismatchedSet($input, $e, $follow) {
if ( $this->mismatchIsMissingToken($input, $follow) ) {
// System.out.println("missing token");
reportError($e);
// we don't know how to conjure up a token for sets yet
return $this->getMissingSymbol($input, $e, TokenConst::$INVALID_TOKEN_TYPE, $follow);
}
// TODO do single token deletion like above for Token mismatch
throw $e;
}
/** Match needs to return the current input symbol, which gets put
* into the label for the associated token ref; e.g., x=ID. Token
* and tree parsers need to return different objects. Rather than test
* for input stream type or change the IntStream interface, I use
* a simple method to ask the recognizer to tell me what the current
* input symbol is.
*
* This is ignored for lexers.
*/
protected function getCurrentInputSymbol($input) { return null; }
/** Conjure up a missing token during error recovery.
*
* The recognizer attempts to recover from single missing
* symbols. But, actions might refer to that missing symbol.
* For example, x=ID {f($x);}. The action clearly assumes
* that there has been an identifier matched previously and that
* $x points at that token. If that token is missing, but
* the next token in the stream is what we want we assume that
* this token is missing and we keep going. Because we
* have to return some token to replace the missing token,
* we have to conjure one up. This method gives the user control
* over the tokens returned for missing tokens. Mostly,
* you will want to create something special for identifier
* tokens. For literals such as '{' and ',', the default
* action in the parser or tree parser works. It simply creates
* a CommonToken of the appropriate type. The text will be the token.
* If you change what tokens must be created by the lexer,
* override this method to create the appropriate tokens.
*/
protected function getMissingSymbol($input, $e, $expectedTokenType, $follow) {
return null;
}
public function consumeUntilMatchesType($input, $tokenType) {
//System.out.println("consumeUntil "+tokenType);
$ttype = $input->LA(1);
while ($ttype != TokenConst::$EOF && $ttype != $tokenType) {
$input->consume();
$ttype = $input->LA(1);
}
}
/** Consume tokens until one matches the given token set */
public function consumeUntilInSet($input, $set) {
//System.out.println("consumeUntil("+set.toString(getTokenNames())+")");
$ttype = $input->LA(1);
while ($ttype != TokenConst::$EOF && !$set->member($ttype) ) {
//System.out.println("consume during recover LA(1)="+getTokenNames()[input.LA(1)]);
$input->consume();
$ttype = $input->LA(1);
}
}
/** Push a rule's follow set using our own hardcoded stack */
protected function pushFollow($fset) {
// if ( ($this->state->_fsp +1)>=sizeof($this->state->following) ) {
// $f = array();
// System.arraycopy(state.following, 0, f, 0, state.following.length-1);
// $this->state->following = f;
// }
$this->state->following[++$this->state->_fsp] = $fset;
}
/** Return List<String> of the rules in your parser instance
* leading up to a call to this method. You could override if
* you want more details such as the file/line info of where
* in the parser java code a rule is invoked.
*
* This is very useful for error messages and for context-sensitive
* error recovery.
*/
/** A more general version of getRuleInvocationStack where you can
* pass in, for example, a RecognitionException to get it's rule
* stack trace. This routine is shared with all recognizers, hence,
* static.
*
* TODO: move to a utility class or something; weird having lexer call this
*/
public static function getRuleInvocationStack($e=null,
$recognizerClassName=null)
{
if($e==null){
$e = new Exception();
}
if($recognizerClassName==null){
$recognizerClassName = get_class($this);
}
throw new Exception("Not implemented yet");
// List rules = new ArrayList();
// StackTraceElement[] stack = e.getStackTrace();
// int i = 0;
// for (i=stack.length-1; i>=0; i--) {
// StackTraceElement t = stack[i];
// if ( t.getClassName().startsWith("org.antlr.runtime.") ) {
// continue; // skip support code such as this method
// }
// if ( t.getMethodName().equals(NEXT_TOKEN_RULE_NAME) ) {
// continue;
// }
// if ( !t.getClassName().equals(recognizerClassName) ) {
// continue; // must not be part of this parser
// }
// rules.add(t.getMethodName());
// }
// return rules;
}
public function getBacktrackingLevel() {
return $this->state->backtracking;
}
/** Used to print out token names like ID during debugging and
* error reporting. The generated parsers implement a method
* that overrides this to point to their String[] tokenNames.
*/
public function getTokenNames() {
return null;
}
/** For debugging and other purposes, might want the grammar name.
* Have ANTLR generate an implementation for this method.
*/
public function getGrammarFileName() {
return null;
}
public abstract function getSourceName();
/** A convenience method for use most often with template rewrites.
* Convert a List<Token> to List<String>
*/
public function toStrings($tokens) {
if ( $tokens==null ) return null;
$strings = array();
for ($i=0; $i<$tokens->size(); $i++) {
$strings[] = $tokens[$i]->getText();
}
return $strings;
}
/** Given a rule number and a start token index number, return
* MEMO_RULE_UNKNOWN if the rule has not parsed input starting from
* start index. If this rule has parsed input starting from the
* start index before, then return where the rule stopped parsing.
* It returns the index of the last token matched by the rule.
*
* For now we use a hashtable and just the slow Object-based one.
* Later, we can make a special one for ints and also one that
* tosses out data after we commit past input position i.
*/
public function getRuleMemoization($ruleIndex, $ruleStartIndex) {
if ( $this->state->ruleMemo[$ruleIndex]==null ) {
$this->state->ruleMemo[$ruleIndex] = array();
}
$stopIndexI =
$this->state->ruleMemo[$ruleIndex][$ruleStartIndex];
if ( $stopIndexI==null ) {
return self::$MEMO_RULE_UNKNOWN;
}
return $stopIndexI;
}
/** Has this rule already parsed input at the current index in the
* input stream? Return the stop token index or MEMO_RULE_UNKNOWN.
* If we attempted but failed to parse properly before, return
* MEMO_RULE_FAILED.
*
* This method has a side-effect: if we have seen this input for
* this rule and successfully parsed before, then seek ahead to
* 1 past the stop token matched for this rule last time.
*/
public function alreadyParsedRule($input, $ruleIndex) {
$stopIndex = $this->getRuleMemoization($ruleIndex, $input->index());
if ( $stopIndex==self::$MEMO_RULE_UNKNOWN ) {
return false;
}
if ( $stopIndex==self::$MEMO_RULE_FAILED ) {
//System.out.println("rule "+ruleIndex+" will never succeed");
$this->state->failed=true;
}
else {
//System.out.println("seen rule "+ruleIndex+" before; skipping ahead to @"+(stopIndex+1)+" failed="+state.failed);
$input->seek($stopIndex+1); // jump to one past stop token
}
return true;
}
/** Record whether or not this rule parsed the input at this position
* successfully. Use a standard java hashtable for now.
*/
public function memoize($input, $ruleIndex, $ruleStartIndex){
$stopTokenIndex = $this->state->failed?self::$MEMO_RULE_FAILED:$input->index()-1;
if ( $this->state->ruleMemo==null ) {
echo("!!!!!!!!! memo array is null for ". getGrammarFileName());
}
if ( $ruleIndex >= sizeof($this->state->ruleMemo) ) {
echo("!!!!!!!!! memo size is ".sizeof($this->state->ruleMemo).", but rule index is ".$ruleIndex);
}
if ( $this->state->ruleMemo[$ruleIndex]!=null ) {
$this->state->ruleMemo[$ruleIndex][$ruleStartIndex] = $stopTokenIndex;
}
}
/** return how many rule/input-index pairs there are in total.
* TODO: this includes synpreds. :(
*/
public function getRuleMemoizationCacheSize() {
$n = 0;
for ($i = 0; $this->state->ruleMemo!=null && $i < sizeof($this->state->ruleMemo); $i++) {
$ruleMap = $this->state->ruleMemo[$i];
if ( $ruleMap!=null ) {
$n += sizeof($ruleMap); // how many input indexes are recorded?
}
}
return $n;
}
public function traceIn($ruleName, $ruleIndex, $inputSymbol) {
echo("enter ".$ruleName." ".$inputSymbol);
if ( $this->state->failed ) {
echo(" failed=".$this->state->failed);
}
if ( $this->state->backtracking>0 ) {
echo(" backtracking=".$this->state->backtracking);
}
echo "\n";
}
public function traceOut($ruleName, $ruleIndex, $inputSymbol) {
echo("exit ".$ruleName." ".$inputSymbol);
if ( $this->state->failed ) {
echo(" failed=".$this->state->failed);
}
if ( $this->state->backtracking>0 ) {
echo(" backtracking="+$this->state->backtracking);
}
echo "\n";
}
public function getToken($name){
if(preg_match("/\d+/", $name)){
return (integer)$name;
}else{
return $this->$name;
}
}
public function getTokenName($tokenId){
}
}
BaseRecognizer::$DEFAULT_TOKEN_CHANNEL = TokenConst::$DEFAULT_CHANNEL;
BaseRecognizer::$HIDDEN = TokenConst::$HIDDEN_CHANNEL;
?>

View File

@ -0,0 +1,65 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class CharStreamConst{
public static $EOF = -1;
}
$CharStream_EOF = -1;
/** A source of characters for an ANTLR lexer */
interface CharStream extends IntStream {
/** For infinite streams, you don't need this; primarily I'm providing
* a useful interface for action code. Just make sure actions don't
* use this on streams that don't support it.
*/
public function substring($start, $stop);
/** Get the ith character of lookahead. This is the same usually as
* LA(i). This will be used for labels in the generated
* lexer code. I'd prefer to return a char here type-wise, but it's
* probably better to be 32-bit clean and be consistent with LA.
*/
public function LT($i);
/** ANTLR tracks the line information automatically */
function getLine();
/** Because this stream can rewind, we need to be able to reset the line */
function setLine($line);
function setCharPositionInLine($pos);
/** The index of the character relative to the beginning of the line 0..n-1 */
function getCharPositionInLine();
}
?>

View File

@ -0,0 +1,4 @@
<?php
class CharStreamState {
}
?>

View File

@ -0,0 +1,4 @@
<?php
?>

View File

@ -0,0 +1,380 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** The most common stream of tokens is one where every token is buffered up
* and tokens are prefiltered for a certain channel (the parser will only
* see these tokens and cannot change the filter channel number during the
* parse).
*
* TODO: how to access the full token stream? How to track all tokens matched per rule?
*/
class CommonTokenStream implements TokenStream {
protected $tokenSource;
/** Record every single token pulled from the source so we can reproduce
* chunks of it later.
*/
protected $tokens;
/** Map<tokentype, channel> to override some Tokens' channel numbers */
protected $channelOverrideMap;
/** Set<tokentype>; discard any tokens with this type */
protected $discardSet;
/** Skip tokens on any channel but this one; this is how we skip whitespace... */
protected $channel;
/** By default, track all incoming tokens */
protected $discardOffChannelTokens = false;
/** Track the last mark() call result value for use in rewind(). */
protected $lastMarker = 0;
/** The index into the tokens list of the current token (next token
* to consume). p==-1 indicates that the tokens list is empty
*/
protected $p = -1;
public function __construct($tokenSource, $channel=null) {
$this->channel = TokenConst::$DEFAULT_CHANNEL;
$this->tokens = array();
$this->tokenSource = $tokenSource;
if($channel != null){
$this->channel = $channel;
}
}
/** Reset this token stream by setting its token source. */
public function setTokenSource($tokenSource) {
$this->tokenSource = $tokenSource;
$this->tokens = array();
$this->p = -1;
$this->channel = TokenConst::$DEFAULT_CHANNEL;
}
/** Load all tokens from the token source and put in tokens.
* This is done upon first LT request because you might want to
* set some token type / channel overrides before filling buffer.
*/
protected function fillBuffer() {
$index = 0;
$t = $this->tokenSource->nextToken();
while ( $t!=null && $t->getType()!=CharStreamConst::$EOF ) {
$discard = false;
// is there a channel override for token type?
if ( $this->channelOverrideMap!=null ) {
$channelI = $this->channelOverrideMap[$t->getType()];
if ( $channelI!=null ) {
$t->setChannel($channelI);
}
}
if ( $this->discardSet!=null &&
$this->discardSet->contains($t->getType()))
{
$discard = true;
}
else if ( $this->discardOffChannelTokens && $t->getChannel()!=$this->channel ) {
$discard = true;
}
if ( !$discard ) {
$t->setTokenIndex($index);
$this->tokens[] = $t;
$index++;
}
$t = $this->tokenSource->nextToken();
}
// leave p pointing at first token on channel
$this->p = 0;
$this->p = $this->skipOffTokenChannels($this->p);
}
/** Move the input pointer to the next incoming token. The stream
* must become active with LT(1) available. consume() simply
* moves the input pointer so that LT(1) points at the next
* input symbol. Consume at least one token.
*
* Walk past any token not on the channel the parser is listening to.
*/
public function consume() {
if ( $this->p<sizeof($this->tokens)) {
$this->p++;
$this->p = $this->skipOffTokenChannels($this->p); // leave p on valid token
}
}
/** Given a starting index, return the index of the first on-channel
* token.
*/
protected function skipOffTokenChannels($i) {
$n = sizeof($this->tokens);
while ( $i<$n && $this->tokens[$i]->getChannel()!=$this->channel ) {
$i++;
}
return $i;
}
protected function skipOffTokenChannelsReverse($i) {
while ( $i>=0 && $this->tokens[$i]->getChannel()!=$this->channel) {
$i--;
}
return $i;
}
/** A simple filter mechanism whereby you can tell this token stream
* to force all tokens of type ttype to be on channel. For example,
* when interpreting, we cannot exec actions so we need to tell
* the stream to force all WS and NEWLINE to be a different, ignored
* channel.
*/
public function setTokenTypeChannel($ttype, $channel) {
if ( $this->channelOverrideMap==null ) {
$this->channelOverrideMap = array();
}
$this->channelOverrideMap[$ttype] = $channel;
}
public function discardTokenType($ttype) {
if ( $this->discardSet==null ) {
$this->discardSet = new Set();
}
$this->discardSet.add($ttype);
}
public function discardOffChannelTokens($discardOffChannelTokens) {
$this->discardOffChannelTokens = $discardOffChannelTokens;
}
public function getTokens() {
if ( $this->p == -1 ) {
$this->fillBuffer();
}
return $this->tokens;
}
public function getTokensBetween($start, $stop) {
return $this->getTokens($start, $stop, null);
}
/** Given a start and stop index, return a List of all tokens in
* the token type BitSet. Return null if no tokens were found. This
* method looks at both on and off channel tokens.
*/
public function getTokensOfTypeInSet($start, $stop, $types) {
if ( $p == -1 ) {
fillBuffer();
}
if ( $stop>=sizeof($this->tokens)) {
$stop=sizeof($this->tokens) - 1;
}
if ( $start<0 ) {
$start=0;
}
if ( $start>$stop ) {
return null;
}
// list = tokens[start:stop]:{Token t, t.getType() in types}
$filteredTokens = array();
for ($i=$start; $i<=$stop; $i++) {
$t = $this->tokens[$i];
if ( $types==null || $types->member($t->getType())) {
$filteredTokens->add($t);
}
}
if ( sizeof($filteredTokens)==0 ) {
$filteredTokens = null;
}
return $filteredTokens;
}
public function getTokensOfTypeInArray($start, $stop, $types) {
return $this->getTokens($start, $stop,new Set(types));
}
public function getTokensofType($start, $stop, $ttype) {
return $this->getTokens($start, $stop, new Set(array(ttype)));
}
/** Get the ith token from the current position 1..n where k=1 is the
* first symbol of lookahead.
*/
public function LT($k) {
if ( $this->p == -1 ) {
$this->fillBuffer();
}
if ( $k==0 ) {
return null;
}
if ( $k<0 ) {
return $this->LB(-$k);
}
//System.out.print("LT(p="+p+","+k+")=");
if ( ($this->p+$k-1) >= sizeof($this->tokens)) {
return TokenConst::$EOF_TOKEN;
}
//System.out.println(tokens.get(p+k-1));
$i = $this->p;
$n = 1;
// find k good tokens
while ( $n<$k ) {
// skip off-channel tokens
$i = $this->skipOffTokenChannels($i+1); // leave p on valid token
$n++;
}
if ( $i>=sizeof($this->tokens)) {
return TokenConst::$EOF_TOKEN;
}
return $this->tokens[$i];
}
/** Look backwards k tokens on-channel tokens */
protected function LB($k) {
//System.out.print("LB(p="+p+","+k+") ");
if ( $this->p == -1 ) {
$this->fillBuffer();
}
if ( $k==0 ) {
return null;
}
if ( ($this->p-$k)<0 ) {
return null;
}
$i = $this->p;
$n = 1;
// find k good tokens looking backwards
while ( $n<=$k ) {
// skip off-channel tokens
$i = $this->skipOffTokenChannelsReverse($i-1); // leave p on valid token
$n++;
}
if ( $i<0 ) {
return null;
}
return $this->tokens[$i];
}
/** Return absolute token i; ignore which channel the tokens are on;
* that is, count all tokens not just on-channel tokens.
*/
public function get($i) {
return $this->tokens[$i];
}
public function LA($i) {
$lt = $this->LT($i);
return $this->LT($i)->getType();
}
public function mark() {
if ( $this->p == -1 ) {
$this->fillBuffer();
}
$this->lastMarker = $this->index();
return $this->lastMarker;
}
public function release($marker) {
// no resources to release
}
public function size() {
return sizeof($this->tokens);
}
public function index() {
return $this->p;
}
public function rewind($marker = null) {
if($marker===null){
$marker = $this->lastmarker;
}
$this->seek($marker);
}
public function reset() {
$this->p = 0;
$this->lastMarker = 0;
}
public function seek($index) {
$this->p = $index;
}
public function getTokenSource() {
return $this->tokenSource;
}
public function getSourceName() {
return $this->getTokenSource()->getSourceName();
}
public function toString() {
if ( $this->p == -1 ) {
$this->fillBuffer();
}
return $this->toStringBetween(0, sizeof($this->tokens)-1);
}
public function toStringBetween($start, $stop) {
if ( $start<0 || $stop<0 ) {
return null;
}
if ( $this->p == -1 ) {
$this->fillBuffer();
}
if ( $stop>=sizeof($this->tokens)) {
$stop = sizeof($this->tokens)-1;
}
$buf = "";
for ($i = $start; $i <= $stop; $i++) {
$t = $this->tokens[$i];
$buf.=$t->getText();
}
return $buf;
}
public function toStringBetweenTokens($start, $stop) {
if ( $start!=null && $stop!=null ) {
return toString($this->start->getTokenIndex(), $this->stop->getTokenIndex());
}
return null;
}
public function __toString(){
return $this->toString();
}
}
?>

215
include/antlr/DFA.php Normal file
View File

@ -0,0 +1,215 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** A DFA implemented as a set of transition tables.
*
* Any state that has a semantic predicate edge is special; those states
* are generated with if-then-else structures in a specialStateTransition()
* which is generated by cyclicDFA template.
*
* There are at most 32767 states (16-bit signed short).
* Could get away with byte sometimes but would have to generate different
* types and the simulation code too. For a point of reference, the Java
* lexer's Tokens rule DFA has 326 states roughly.
*/
class DFA {
protected $eot;
protected $eof;
protected $min;
protected $max;
protected $accept;
protected $special;
protected $transition;
protected $decisionNumber;
/** Which recognizer encloses this DFA? Needed to check backtracking */
protected $recognizer;
public $debug = false;
/** From the input stream, predict what alternative will succeed
* using this DFA (representing the covering regular approximation
* to the underlying CFL). Return an alternative number 1..n. Throw
* an exception upon error.
*/
//TODO: This is a hackish way of doing a try finally, replace this by bunching up the returns.
//Possibly rewrite predict. There is one more place i might need to fix, where i thought
//try{}catch(ex){[work]; throw ex}; [work]; would be the same as a try finally;
public function predict($input){
if ( $this->debug ) {
echo ("Enter DFA.predict for decision ".$this->decisionNumber);
}
$mark = $input->mark(); // remember where decision started in input
try {
$ret = $this->_predict($input);
}
catch(Exception $e) {
$input->rewind($mark);
throw $e;
}
$input->rewind($mark);
return $ret;
}
public function _predict($input) {
$s = 0; // we always start at s0
while ( true ) {
if ( $this->debug ) echo ("DFA ".$this->decisionNumber." state ".$s." LA(1)=".$input->LA(1)."(".$input->LA(1)."), index=".$input->index());
$specialState = $this->special[$s];
if ( $specialState>=0 ) {
if ( $this->debug ) {
echo ("DFA ".$this->decisionNumber.
" state ".$s." is special state ".$specialState);
}
$s = $this->specialStateTransition($specialState, $input);
if ( $this->debug ) {
echo ("DFA ".$this->decisionNumber.
" returns from special state ".$specialState." to ".s);
}
if ( $s==-1 ) {
$this->noViableAlt($s, $input);
return 0;
}
$input->consume();
continue;
}
if ( $this->accept[$s] >= 1 ) {
if ( $this->debug ) echo ("accept; predict "+$this->accept[$s]+" from state "+$this->s);
return $this->accept[$s];
}
// look for a normal char transition
$c = $input->LA(1); // -1 == \uFFFF, all tokens fit in 65000 space
if ($c>=$this->min[$s] && $c<=$this->max[$s]) {
$snext = $this->transition[$s][$c-$this->min[$s]]; // move to next state
if ( $snext < 0 ) {
// was in range but not a normal transition
// must check EOT, which is like the else clause.
// eot[s]>=0 indicates that an EOT edge goes to another
// state.
if ( $this->eot[$s]>=0 ) { // EOT Transition to accept state?
if ( $this->debug ) echo("EOT transition");
$s = $this->eot[$s];
$input->consume();
// TODO: I had this as return accept[eot[s]]
// which assumed here that the EOT edge always
// went to an accept...faster to do this, but
// what about predicated edges coming from EOT
// target?
continue;
}
$this->noViableAlt($s,$input);
return 0;
}
$s = $snext;
$input->consume();
continue;
}
if ( $eot[$s]>=0 ) { // EOT Transition?
if ( $this->debug ) println("EOT transition");
$s = $this->eot[$s];
$input->consume();
continue;
}
if ( $c==Token::$EOF && $eof[$s]>=0 ) { // EOF Transition to accept state?
if ( $this->debug ) echo ("accept via EOF; predict "+$this->accept[$eof[$s]]+" from "+$eof[$s]);
return $this->accept[$eof[$s]];
}
// not in range and not EOF/EOT, must be invalid symbol
if ( $this->debug ) {
echo("min[".$s."]=".$this->min[$s]);
echo("max[".$s."]=".$this->max[$s]);
echo("eot[".$s."]=".$this->eot[$s]);
echo("eof[".$s."]=".$this->eof[$s]);
for ($p=0; $p<$this->transition[$s]->length; $p++) {
echo $this->transition[$s][$p]+" ";
}
echo "\n";
}
$this->noViableAlt($s, $input);
return 0;
}
}
function noViableAlt($s, $input){
if ($this->recognizer->state->backtracking>0) {
$this->recognizer->state->failed=true;
return;
}
$nvae =
new NoViableAltException($this->getDescription(),
$decisionNumber,
$s,
$input);
$this->error($nvae);
throw $nvae;
}
/** A hook for debugging interface */
protected function error($nvae) { ; }
function specialStateTransition($s, $input)
{
return -1;
}
public function getDescription() {
return "n/a";
}
/** Given a String that has a run-length-encoding of some unsigned shorts
* like "\1\2\3\9", convert to short[] {2,9,9,9}. We do this to avoid
* static short[] which generates so much init code that the class won't
* compile. :(
*/
public static function unpackEncodedString($encodedString) {
$data = array();
$di = 0;
for ($i=0,$len=strlen($encodedString); $i<$len; $i+=2) {
$n = charAt($encodedString, $i);
$v = charAt($encodedString, $i+1);
// add v n times to data
for ($j=1; $j<=$n; $j++) {
if($v==0xff) $v=-1;
$data[$di++] = $v;
}
}
return $data;
}
function __call($fn, $params){
return call_user_func_array(array($this->recognizer, $fn), $params);
}
}
?>

View File

@ -0,0 +1,40 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** The recognizer did not match anything for a (..)+ loop. */
class EarlyExitException extends RecognitionException {
public $decisionNumber;
public function __construct($decisionNumber, $input) {
parent::__construct($input);
$this->decisionNumber = $decisionNumber;
}
}
?>

112
include/antlr/IntStream.php Normal file
View File

@ -0,0 +1,112 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** A simple stream of integers used when all I care about is the char
* or token type sequence (such as interpretation).
*/
interface IntStream {
function consume();
/** Get int at current input pointer + i ahead where i=1 is next int.
* Negative indexes are allowed. LA(-1) is previous token (token
* just matched). LA(-i) where i is before first token should
* yield -1, invalid char / EOF.
*/
function LA($i);
/** Tell the stream to start buffering if it hasn't already. Return
* current input position, index(), or some other marker so that
* when passed to rewind() you get back to the same spot.
* rewind(mark()) should not affect the input cursor. The Lexer
* track line/col info as well as input index so its markers are
* not pure input indexes. Same for tree node streams.
*/
function mark();
/** Return the current input symbol index 0..n where n indicates the
* last symbol has been read. The index is the symbol about to be
* read not the most recently read symbol.
*/
function index();
/** Reset the stream so that next call to index would return marker.
* The marker will usually be index() but it doesn't have to be. It's
* just a marker to indicate what state the stream was in. This is
* essentially calling release() and seek(). If there are markers
* created after this marker argument, this routine must unroll them
* like a stack. Assume the state the stream was in when this marker
* was created.
*/
function rewind($marker=null);
/** You may want to commit to a backtrack but don't want to force the
* stream to keep bookkeeping objects around for a marker that is
* no longer necessary. This will have the same behavior as
* rewind() except it releases resources without the backward seek.
* This must throw away resources for all markers back to the marker
* argument. So if you're nested 5 levels of mark(), and then release(2)
* you have to release resources for depths 2..5.
*/
function release($marker);
/** Set the input cursor to the position indicated by index. This is
* normally used to seek ahead in the input stream. No buffering is
* required to do this unless you know your stream will use seek to
* move backwards such as when backtracking.
*
* This is different from rewind in its multi-directional
* requirement and in that its argument is strictly an input cursor (index).
*
* For char streams, seeking forward must update the stream state such
* as line number. For seeking backwards, you will be presumably
* backtracking using the mark/rewind mechanism that restores state and
* so this method does not need to update state when seeking backwards.
*
* Currently, this method is only used for efficient backtracking using
* memoization, but in the future it may be used for incremental parsing.
*
* The index is 0..n-1. A seek to position i means that LA(1) will
* return the ith symbol. So, seeking to 0 means LA(1) will return the
* first element in the stream.
*/
function seek($index);
/** Only makes sense for streams that buffer everything up probably, but
* might be useful to display the entire stream or for testing. This
* value includes a single EOF.
*/
function size();
/** Where are you getting symbols from? Normally, implementations will
* pass the buck all the way to the lexer who can ask its input stream
* for the file name or whatever.
*/
public function getSourceName();
}
?>

View File

@ -0,0 +1,46 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class MismatchedRangeException extends RecognitionException {
public $a;
public $b;
public function __construct($a, $b, $input) {
parent::__construct($input);
$this->a = $a;
$this->b = $b;
}
public function __toString() {
return "MismatchedNotSetException(".$this->getUnexpectedType()." not in [".a.",".b."])";
}
}
?>

View File

@ -0,0 +1,43 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class MismatchedSetException extends RecognitionException {
public $expecting;
public function __construct($expecting, $input) {
parent::__construct($input);
$this->expecting = $expecting;
}
public function __toString() {
return "MismatchedSetException(".$this->getUnexpectedType()."!=".$this->expecting.")";
}
}
?>

View File

@ -0,0 +1,42 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** A mismatched char or Token or tree node */
class MismatchedTokenException extends RecognitionException {
//$expecting = $Token_INVALID_TOKEN_TYPE
public function __construct($expecting=0, $input=null) {
parent::__construct($input);
$this->expecting = $expecting;
}
public function __toString() {
return "MismatchedTokenException(".$this->getUnexpectedType()."!=".$this->expecting.")";
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** We were expecting a token but it's not found. The current token
* is actually what we wanted next. Used for tree node errors too.
*/
class MissingTokenException extends MismatchedTokenException {
public $inserted;
public function __construct($expecting, $input, $inserted) {
parent::__construct($expecting, $input);
$this->inserted = $inserted;
}
public function getMissingType() {
return $this->expecting;
}
public function toString() {
if ( $this->inserted!=null && $this->token!=null ) {
return "MissingTokenException(inserted ".$this->inserted." at ".$this->token->getText()+")";
}
if ( $this->token!=null ) {
return "MissingTokenException(at ".$token->getText().")";
}
return "MissingTokenException";
}
}
?>

View File

@ -0,0 +1,55 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class NoViableAltException extends RecognitionException {
public $grammarDecisionDescription;
public $decisionNumber;
public $stateNumber;
public function __construct($grammarDecisionDescription,
$decisionNumber,
$stateNumber,
$input)
{
parent::__construct($input);
$this->grammarDecisionDescription = $grammarDecisionDescription;
$this->decisionNumber = $decisionNumber;
$this->stateNumber = $stateNumber;
}
public function __toString() {
if ( $this->input instanceof CharStream ) {
return "NoViableAltException('".$this->getUnexpectedType()."'@[".$this->grammarDecisionDescription."])";
}
else {
return "NoViableAltException(".$this->getUnexpectedType()."@[".$this->grammarDecisionDescription."])";
}
}
}
?>

View File

@ -0,0 +1,179 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** The root of the ANTLR exception hierarchy.
*
* To avoid English-only error messages and to generally make things
* as flexible as possible, these exceptions are not created with strings,
* but rather the information necessary to generate an error. Then
* the various reporting methods in Parser and Lexer can be overridden
* to generate a localized error message. For example, MismatchedToken
* exceptions are built with the expected token type.
* So, don't expect getMessage() to return anything.
*
* Note that as of Java 1.4, you can access the stack trace, which means
* that you can compute the complete trace of rules from the start symbol.
* This gives you considerable context information with which to generate
* useful error messages.
*
* ANTLR generates code that throws exceptions upon recognition error and
* also generates code to catch these exceptions in each rule. If you
* want to quit upon first error, you can turn off the automatic error
* handling mechanism using rulecatch action, but you still need to
* override methods mismatch and recoverFromMismatchSet.
*
* In general, the recognition exceptions can track where in a grammar a
* problem occurred and/or what was the expected input. While the parser
* knows its state (such as current input symbol and line info) that
* state can change before the exception is reported so current token index
* is computed and stored at exception time. From this info, you can
* perhaps print an entire line of input not just a single token, for example.
* Better to just say the recognizer had a problem and then let the parser
* figure out a fancy report.
*/
class RecognitionException extends Exception {
public $line=0;
public function __construct($input) {
/** What input stream did the error occur in? */
$this->input = $input;
/** What is index of token/char were we looking at when the error occurred? */
$this->index = $input->index();
/** The current Token when an error occurred. Since not all streams
* can retrieve the ith Token, we have to track the Token object.
* For parsers. Even when it's a tree parser, token might be set.
*/
$this->token=null;
/** If this is a tree parser exception, node is set to the node with
* the problem.
*/
$this->node=null;
/** The current char when an error occurred. For lexers. */
$this->c=0;
/** Track the line at which the error occurred in case this is
* generated from a lexer. We need to track this since the
* unexpected char doesn't carry the line info.
*/
$this->line=0;
$this->charPositionInLine=0;
/** If you are parsing a tree node stream, you will encounter som
* imaginary nodes w/o line/col info. We now search backwards looking
* for most recent token with line/col info, but notify getErrorHeader()
* that info is approximate.
*/
$this->approximateLineInfo=false;
if ( $this->input instanceof TokenStream ) {
$this->token = $input->LT(1);
$this->line = $this->token->getLine();
$this->charPositionInLine = $this->token->getCharPositionInLine();
}
if ( $this->input instanceof TreeNodeStream ) {
$this->extractInformationFromTreeNodeStream($input);
}
else if ( $input instanceof CharStream ) {
$this->c = $input->LA(1);
$this->line = $input->getLine();
$this->charPositionInLine = $input->getCharPositionInLine();
}
else {
$this->c = $input->LA(1);
}
}
protected function extractInformationFromTreeNodeStream($input) {
$nodes = $input;
$this->node = $nodes->LT(1);
$adaptor = $nodes->getTreeAdaptor();
$payload = $adaptor->getToken($this->node);
if ( $payload!=null ) {
$this->token = $payload;
if ( $payload->getLine()<= 0 ) {
// imaginary node; no line/pos info; scan backwards
$i = -1;
$priorNode = $nodes->LT($i);
while ( $priorNode!=null ) {
$priorPayload = $adaptor->getToken($priorNode);
if ( $priorPayload!=null && $priorPayload->getLine()>0 ) {
// we found the most recent real line / pos info
$this->line = $priorPayload->getLine();
$this->charPositionInLine = $priorPayload->getCharPositionInLine();
$this->approximateLineInfo = true;
break;
}
--$i;
$priorNode = $nodes->LT($i);
}
}
else { // node created from real token
$this->line = $payload->getLine();
$this->charPositionInLine = $payload->getCharPositionInLine();
}
}
else if ( $this->node instanceof Tree) {
$this->line = $this->node->getLine();
$this->charPositionInLine = $this->node->getCharPositionInLine();
if ( $this->node instanceof CommonTree) {
$this->token = $this->node->token;
}
}
else {
$type = $adaptor->getType($this->node);
$text = $adaptor->getText($this->node);
$this->token = CommonToken::forTypeAndText($type, $text);
}
}
/** Return the token type or char of the unexpected input element */
public function getUnexpectedType() {
if ( $this->input instanceof TokenStream ) {
return $this->token->getType();
}
else if ( $this->input instanceof TreeNodeStream ) {
$nodes = $this->input;
$adaptor = $nodes->getTreeAdaptor();
return $adaptor->getType($this->node);
}
else {
return $this->c;
}
}
}
?>

View File

@ -0,0 +1,87 @@
<?php
class RecognizerSharedState {
public function __construct(){
/** Track the set of token types that can follow any rule invocation.
* Stack grows upwards. When it hits the max, it grows 2x in size
* and keeps going.
*/
$this->following = array(); //Should be an array of bitsets
$this->_fsp = -1;
//public BitSet[] following = new BitSet[BaseRecognizer.INITIAL_FOLLOW_STACK_SIZE];
/** This is true when we see an error and before having successfully
* matched a token. Prevents generation of more than one error message
* per error.
*/
$this->errorRecovery = false;
/** The index into the input stream where the last error occurred.
* This is used to prevent infinite loops where an error is found
* but no token is consumed during recovery...another error is found,
* ad naseum. This is a failsafe mechanism to guarantee that at least
* one token/tree node is consumed for two errors.
*/
$this->lastErrorIndex = -1;
/** In lieu of a return value, this indicates that a rule or token
* has failed to match. Reset to false upon valid token match.
*/
$this->failed=false;
/** Did the recognizer encounter a syntax error? Track how many. */
$this->syntaxErrors=0;
/** If 0, no backtracking is going on. Safe to exec actions etc...
* If >0 then it's the level of backtracking.
*/
$this->backtracking = 0;
/** An array[size num rules] of Map<Integer,Integer> that tracks
* the stop token index for each rule. ruleMemo[ruleIndex] is
* the memoization table for ruleIndex. For key ruleStartIndex, you
* get back the stop token for associated rule or MEMO_RULE_FAILED.
*
* This is only used if rule memoization is on (which it is by default).
*/
$this->ruleMemo = null;
// LEXER FIELDS (must be in same state object to avoid casting
// constantly in generated code and Lexer object) :(
/** The goal of all lexer rules/methods is to create a token object.
* This is an instance variable as multiple rules may collaborate to
* create a single token. nextToken will return this object after
* matching lexer rule(s). If you subclass to allow multiple token
* emissions, then set this to the last token to be matched or
* something nonnull so that the auto token emit mechanism will not
* emit another token.
*/
$this->token = null;
/** What character index in the stream did the current token start at?
* Needed, for example, to get the text for current token. Set at
* the start of nextToken.
*/
$this->tokenStartCharIndex = -1;
/** The line on which the first character of the token resides */
$this->tokenStartLine = 0;
/** The character position of first character within the line */
$this->tokenStartCharPositionInLine = 0;
/** The channel number for the current token */
$this->channel = 0;
/** The token type for the current token */
$this->type = 0;
/** You can set the text for the current token to override what is in
* the input char buffer. Use setText() or can set this instance var.
*/
$this->text=null;
}
}
?>

34
include/antlr/Set.php Normal file
View File

@ -0,0 +1,34 @@
<?php
//Todo: find a decent set implementation for php
class Set{
public function __construct($arr){
$this->store = array();
foreach($arr as $el){
$this->store[$el] = $el;
}
}
public function add($value){
$this->store[$value] = $value;
}
public function member($value){
return array_key_exists($value, $this->store);
}
public function union($otherSet){
return new Set(array_merge($this->store, $otherSet->store));
}
public function unionInPlace($otherSet){
$this->store = $this->union($otherSet)->store;
}
public function remove($value){
unset($this->store[$value]);
}
}
?>

222
include/antlr/Token.php Normal file
View File

@ -0,0 +1,222 @@
<?php
class TokenConst{
public static $EOR_TOKEN_TYPE = 1;
/** imaginary tree navigation type; traverse "get child" link */
public static $DOWN = 2;
/** imaginary tree navigation type; finish with a child list */
public static $UP = 3;
public static $MIN_TOKEN_TYPE;// = UP+1;
public static $EOF;// = CharStream.EOF;
public static $EOF_TOKEN;// = new CommonToken(EOF);
public static $INVALID_TOKEN_TYPE = 0;
public static $INVALID_TOKEN;// = new CommonToken(INVALID_TOKEN_TYPE);
/** In an action, a lexer rule can set token to this SKIP_TOKEN and ANTLR
* will avoid creating a token for this symbol and try to fetch another.
*/
public static $SKIP_TOKEN;// = new CommonToken(INVALID_TOKEN_TYPE);
/** All tokens go to the parser (unless skip() is called in that rule)
* on a particular "channel". The parser tunes to a particular channel
* so that whitespace etc... can go to the parser on a "hidden" channel.
*/
public static $DEFAULT_CHANNEL = 0;
/** Anything on different channel than DEFAULT_CHANNEL is not parsed
* by parser.
*/
public static $HIDDEN_CHANNEL = 99;
}
interface Token{
}
class CommonToken implements Token {
function __construct(){
}
public static function forInput($input=null, $type, $channel=0, $start=0, $stop=0) {
$ct = new CommonToken();
$ct->charPositionInLine=-1;
$ct->input = $input;
$ct->type = $type;
$ct->channel = $channel;
$ct->start = $start;
$ct->stop = $stop;
return $ct;
}
public static function forType($type){
return CommonToken::forInput($input=null, $type);
}
public static function forTypeAndText($type, $text) {
$ct = new CommonToken();
$ct->type = $type;
$ct->channel = TokenConst::$DEFAULT_CHANNEL;
$ct->text = $text;
return $ct;
}
/*
public CommonToken(Token oldToken) {
text = oldToken.getText();
type = oldToken.getType();
line = oldToken.getLine();
index = oldToken.getTokenIndex();
charPositionInLine = oldToken.getCharPositionInLine();
channel = oldToken.getChannel();
if ( oldToken instanceof CommonToken ) {
start = ((CommonToken)oldToken).start;
stop = ((CommonToken)oldToken).stop;
}
}
*/
public function getType() {
return $this->type;
}
public function setLine($line) {
$this->line = $this->line;
}
public function getText() {
if ( $this->text!=null ) {
return $this->text;
}
if ( $this->input==null ) {
return null;
}
$this->text = $this->input->substring($this->start,$this->stop);
return $this->text;
}
/** Override the text for this token. getText() will return this text
* rather than pulling from the buffer. Note that this does not mean
* that start/stop indexes are not valid. It means that that input
* was converted to a new string in the token object.
*/
public function setText($text) {
$this->text = $this->text;
}
public function getLine() {
return $this->line;
}
public function getCharPositionInLine() {
return $this->charPositionInLine;
}
public function setCharPositionInLine($charPositionInLine) {
$this->charPositionInLine = $this->charPositionInLine;
}
public function getChannel() {
return $this->channel;
}
public function setChannel($channel) {
$this->channel = $this->channel;
}
public function setType($type) {
$this->type = $this->type;
}
public function getStartIndex() {
return $this->start;
}
public function setStartIndex($start) {
$this->start = $this->start;
}
public function getStopIndex() {
return $this->stop;
}
public function setStopIndex($stop) {
$this->stop = $this->stop;
}
public function getTokenIndex() {
return $this->index;
}
public function setTokenIndex($index) {
$this->index = $this->index;
}
public function getInputStream() {
return $this->input;
}
public function setInputStream($input) {
$this->input = $this->input;
}
public function toString() {
$channelStr = "";
if ( $this->channel>0 ) {
$channelStr=",channel=".$this->channel;
}
$txt = $this->getText();
if ( $txt!=null ) {
$txt = str_replace("\n",'\n', $txt);
$txt = str_replace("\r",'\r', $txt);
$txt = str_replace("\t",'\t', $txt);
}
else {
$txt = "<no text>";
}
return "[@".$this->getTokenIndex().",".$this->start.":".$this->stop."='".$txt."',<".$this->type.">".$channelStr.",".$this->line.":".$this->getCharPositionInLine()."]";
}
public function __toString(){
return $this->toString();
}
}
TokenConst::$DEFAULT_CHANNEL=0;
TokenConst::$INVALID_TOKEN_TYPE=0;
TokenConst::$EOF = CharStreamConst::$EOF;
TokenConst::$EOF_TOKEN = CommonToken::forType(TokenConst::$EOF);
TokenConst::$INVALID_TOKEN_TYPE = 0;
TokenConst::$INVALID_TOKEN = CommonToken::forType(TokenConst::$INVALID_TOKEN_TYPE);
/** In an action, a lexer rule can set token to this SKIP_TOKEN and ANTLR
* will avoid creating a token for this symbol and try to fetch another.
*/
TokenConst::$SKIP_TOKEN = CommonToken::forType(TokenConst::$INVALID_TOKEN_TYPE);
/** All tokens go to the parser (unless skip() is called in that rule)
* on a particular "channel". The parser tunes to a particular channel
* so that whitespace etc... can go to the parser on a "hidden" channel.
*/
TokenConst::$DEFAULT_CHANNEL = 0;
/** Anything on different channel than DEFAULT_CHANNEL is not parsed
* by parser.
*/
TokenConst::$HIDDEN_CHANNEL = 99;
TokenConst::$MIN_TOKEN_TYPE = TokenConst::$UP+1;
?>

View File

@ -0,0 +1,71 @@
<?php
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** A stream of tokens accessing tokens from a TokenSource */
interface TokenStream extends IntStream {
/** Get Token at current input pointer + i ahead where i=1 is next Token.
* i<0 indicates tokens in the past. So -1 is previous token and -2 is
* two tokens ago. LT(0) is undefined. For i>=n, return Token.EOFToken.
* Return null for LT(0) and any index that results in an absolute address
* that is negative.
*/
public function LT($k);
/** Get a token at an absolute index i; 0..n-1. This is really only
* needed for profiling and debugging and token stream rewriting.
* If you don't want to buffer up tokens, then this method makes no
* sense for you. Naturally you can't use the rewrite stream feature.
* I believe DebugTokenStream can easily be altered to not use
* this method, removing the dependency.
*/
public function get($i);
/** Where is this stream pulling tokens from? This is not the name, but
* the object that provides Token objects.
*/
public function getTokenSource();
/** Return the text of all tokens from start to stop, inclusive.
* If the stream does not buffer all the tokens then it can just
* return "" or null; Users should not access $ruleLabel.text in
* an action of course in that case.
*/
public function toStringBetween($start, $stop);
/** Because the user is not required to use a token with an index stored
* in it, we must provide a means for two token objects themselves to
* indicate the start/end location. Most often this will just delegate
* to the other toString(int,int). This is also parallel with
* the TreeNodeStream.toString(Object,Object).
*/
public function toStringBetweenTokens($start, $stop);
}
?>

Some files were not shown because too many files have changed in this diff Show More