Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • vtiger/vtigercrm
  • varma/vtigercrm
  • alanbell/vtigercrm
  • mariusz.krzaczkowski/vtigercrm
  • manu.k/vtigercrm
  • adrgranado/vtigercrm
  • uma.s/vtigercrm
  • sardoj/vtigercrm
  • preexo/vtigercrm
  • david.valminos/vtigercrm
  • luca.saba/vtigercrm
  • dubwise/vtigercrm
  • valmir.ttcasolucoes/vtigercrm
  • lord_alan/vtigercrm
  • adrien.futschik/vtigercrm
  • edonit.rexhepi/vtigercrm
  • robert.heinze/vtigercrm
  • nrdimatteo/vtigercrm
  • sebastianzahan/vtigercrm
  • Miky/vtigercrm
  • germanf/vtigercrm
  • bernhardkau1/vtigercrm
  • olegtsoy/vtigercrm
  • grandel/vtigercrm
  • mario.thummler/vtigercrm
  • sutharsan/vtigercrm
  • james.douglas/vtigercrm
  • vikas/vtigercrm
  • jeffmchristensen/vtigercrm
  • lukasz.g/vtigercrm
  • nicolas.gasnier/vtigercrm
  • hamish.theitcompany/vtigercrm
  • engrbm87/vtigercrm
  • Quoc/vtigercrm
  • peter.maria.engeli/vtigercrm
  • kiranraju.j/vtigercrm
  • manuel.lozano/vtigercrm
  • dhaupin/vtigercrm
  • Ragupathyranesh/vtigercrm
  • Stefanbauer/vtigercrm
  • ruben.estrada/vtigercrm
  • sg_mwi1/vtigercrm
  • khaluk/vtigercrm
  • franzfroemel/vtigercrm
  • milan9615/vtigercrm
  • carlos.martin/vtigercrm
  • cmaggi/vtigercrm
  • Soltoon.theLeader/vtigercrm
  • alex.kaplun/vtigercrm
  • navid.hosseini/vtigercrm
  • maie/vtigercrm
  • simonetravaglini/vtigercrm
  • bertrand.wattel/vtigercrm
  • balaji.m/vtigercrm
  • mclarke4/vtigercrm
  • lajeeshk/vtigercrm
  • liam/vtigercrm
  • novikov.sergey/vtigercrm
  • johnwayne.williamson/vtigercrm
  • florian.strahberger-schramm/vtigercrm
  • daniel.schaefer/vtigercrm
  • christopher.gunther/vtigercrm
  • adrien.faveraux/vtigercrm
  • carsten.brandt/vtigercrm
  • stephane.molano/vtigercrm
  • krastan.petrov/vtigercrm
  • alfredo.bravo/vtigercrm
  • flipflop.Joe/vtigercrm
  • mirko.stagni/vtigercrm
  • remigio.ruberto/vtigercrm
  • gautam.dhudashiya/vtigercrm
  • manish.devitechnosolutions1/vtigercrm
  • matinbeigi/vtigercrm
  • devs/vtigercrm
  • happy.dev/vtigercrm
  • m.gigon/vtigercrm
  • manuelmigone/vtigercrm
  • eduardo.gqf/vtigercrm
  • elsayedEl-araby/vtigercrm
  • mirza.mehran/vtigercrm
  • maurice.courtois/vtigercrm
  • zuhri.utama/vtigercrm
  • shilpa.k/vtigercrm
  • Ignazio/vtigercrm
  • code80team/vtigercrm
  • code80/vtigercrm
  • nilay.automatesmb/cache
  • greeshma.kk/vtigercrm
  • vijay.tilak/vtigercrm
  • Paolo.Palamini/vtigercrm
  • estevan/vtigercrm
  • mobilcmcdk/vtigercrm
  • massimiliano.vessi/vtigercrm
  • daniel.voelskow/vtigercrm
  • james1/vtigercrm
  • lokesh.s/vtigercrm
  • rdb/vtigercrm
  • neftaliyagua/vtigercrm
  • angelo.paglialonga/vtigercrm
  • webmarka/vtigercrm
  • javanile/vtigercrm
  • akshath/vtigercrm
  • Hemanth/vtigercrm
  • opencrmitalia/vtigercrm
  • direzione/vtigercrm
  • umadas306/vtigercrm
  • jd-wraptec/vtigercrm
  • felipe.camacho/vtigercrm
  • Martin.allen/vtigercrm
  • amit.r/vtigercrm
  • vicus/vtigercrm
  • dev.osmi/vtigercrm
  • laurent.guillout/vtigercrm
  • christian.blaeul/vtigercrm
  • ap.js100/vtigercrm
  • yoann.mourot/vtigercrm-temp
  • christian.cruz/vtigercrm
  • zyli/vtigercrm
  • kaushik.p/vtigercrm
  • Madhuk/vtigercrm
  • cinakzm/vtigercrm
  • raquel.martinez/vtigercrm
  • tosajibadhi/vtigercrm
  • melvin.i/vtigercrm-melvin
  • ashashingadia/vtigercrm
  • stefanwarnat/vtigercrm
  • saran.s/vtigercrm
  • eduardomozart/vtigercrm
  • Daniel.Lennartz1/vtigercrm
  • juergen.fassmann/vtigercrm
  • Michel.Ram/vtigercrm
  • vincenzo.bruno/vtigercrm
132 results
Show changes
Commits on Source (2637)
Showing
with 1699 additions and 2707 deletions
vendor/*
!vendor/.htaccess
.vscode/*
\ No newline at end of file
......@@ -99,6 +99,7 @@ $GLOBALS['_PEAR_error_handler_stack'] = array();
* @since Class available since PHP 4.0.2
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
*/
#[\AllowDynamicProperties]
class PEAR
{
// {{{ properties
......@@ -156,7 +157,7 @@ class PEAR
// }}}
// {{{ constructor
/**
* Constructor. Registers this object in
* $_PEAR_destructor_object_list for destructor emulation if a
......@@ -167,7 +168,7 @@ class PEAR
* @access public
* @return void
*/
function PEAR($error_class = null)
function __construct($error_class = null)
{
$classname = strtolower(get_class($this));
if ($this->_debug) {
......@@ -191,6 +192,13 @@ class PEAR
}
}
}
function PEAR($error_class = null)
{
// PHP4-style constructor.
// This will NOT be invoked, unless a sub-class that extends `foo` calls it.
// In that case, call the new-style constructor to keep compatibility.
self::__construct($error_class);
}
// }}}
// {{{ destructor
......@@ -227,7 +235,7 @@ class PEAR
* @return mixed A reference to the variable. If not set it will be
* auto initialised to NULL.
*/
function &getStaticProperty($class, $var)
static function &getStaticProperty($class, $var)
{
static $properties;
return $properties[$class][$var];
......@@ -245,7 +253,7 @@ class PEAR
* @param mixed $args The arguments to pass to the function
* @return void
*/
function registerShutdownFunc($func, $args = array())
static function registerShutdownFunc($func, $args = array())
{
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
}
......@@ -264,7 +272,7 @@ class PEAR
* @access public
* @return bool true if parameter is an error
*/
function isError($data, $code = null)
static function isError($data, $code = null)
{
if (is_a($data, 'PEAR_Error')) {
if (is_null($code)) {
......@@ -320,7 +328,7 @@ class PEAR
* @since PHP 4.0.5
*/
function setErrorHandling($mode = null, $options = null)
static function setErrorHandling($mode = null, $options = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$setmode = $this->_default_error_mode;
......@@ -509,7 +517,7 @@ class PEAR
* @see PEAR::setErrorHandling
* @since PHP 4.0.5
*/
function &raiseError($message = null,
static function &raiseError($message = null,
$code = null,
$mode = null,
$options = null,
......@@ -807,6 +815,7 @@ function _PEAR_call_destructors()
* @see PEAR::raiseError(), PEAR::throwError()
* @since Class available since PHP 4.0.2
*/
#[\AllowDynamicProperties]
class PEAR_Error
{
// {{{ properties
......@@ -842,7 +851,7 @@ class PEAR_Error
* @access public
*
*/
function PEAR_Error($message = 'unknown error', $code = null,
function __construct($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
if ($mode === null) {
......@@ -900,6 +909,15 @@ class PEAR_Error
eval('$e = new Exception($this->message, $this->code);throw($e);');
}
}
function PEAR_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
// PHP4-style constructor.
// This will NOT be invoked, unless a sub-class that extends `foo` calls it.
// In that case, call the new-style constructor to keep compatibility.
self::__construct($message, $code,$mode, $options, $userinfo);
}
// }}}
// {{{ getMode()
......
Vtiger CRM
==========
# Vtiger CRM
Vtiger is a PHP based web application that enables businesses to increase sales wins, marketing ROI, and support satisfaction by providing tools for employees and management work more effectively, capture more data, and derive new actionable insights from across the customer lifecycle.
Get involved
------------
## Get involved
Development on vtiger is done at http://code.vtiger.com
Development on vtiger is done at https://code.vtiger.com
**Note**: Any contributions submitted to Vtiger project should be made available under Vtiger Public License.
If contribution has any patented code, or commercial code, then please communicate with Vtiger team before making the contribution.
https://www.vtiger.com/vtiger-public-license/
To register for an account, please contact info @ vtiger.com, you will need this to file issues and/or fix the code
Once you have an account, you can [browse the code](http://code.vtiger.com/vtiger/vtigercrm/tree/master),
[see if your issue is already reported](http://code.vtiger.com/vtiger/vtigercrm/issues) and if you have a new problem
to report you can [create an issue](http://code.vtiger.com/vtiger/vtigercrm/issues/new?issue)
To register for an account, please contact community @ vtiger.com, you will need this to file issues and/or fix the code
Once you have an account, you can [browse the code](https://code.vtiger.com/vtiger/vtigercrm/tree/master),
[see if your issue is already reported](https://code.vtiger.com/vtiger/vtigercrm/issues) and if you have a new problem
to report you can [create an issue](https://code.vtiger.com/vtiger/vtigercrm/issues/new?issue)
If you then want to fix the issue (or another issue) you can create your own fork of vtiger to work on using the
fork button on the vtiger project, this will create a new git repository for you at
http://code.vtiger.com/yourname/vtigercrm.git
https://code.vtiger.com/yourname/vtigercrm.git
on your computer you will need a git client installed and you need to tell git who you are:
......@@ -30,7 +28,7 @@ on your computer you will need a git client installed and you need to tell git w
now clone your fork of vtiger
git clone http://code.vtiger.com/yourname/vtigercrm.git
git clone https://code.vtiger.com/yourname/vtigercrm.git
this will pull down from the server your copy of the vtiger code and all the history.
......@@ -40,6 +38,8 @@ you will switch to that branch using the checkout command
git branch fix_projects_on_calendar
git checkout fix_projects_on_calendar
Before you install, you need to run ```composer update```
Now you can make your changes and commit all changed files with
git commit -a
......@@ -63,7 +63,6 @@ And you can create additional feature branches from there to fix different thing
If there have been other changes to the central vtiger code that you want in your work area then you can add the central
repository as an upstream remote (only need to do this bit once), then you can fetch changes and merge them
git remote add upstream http://code.vtiger.com/vtiger/vtigercrm.git
git remote add upstream https://code.vtiger.com/vtiger/vtigercrm.git
git fetch upstream
git merge upstream/master
......@@ -28,7 +28,7 @@ require("config.php");
global $adb;
global $log;
global $HELPDESK_SUPPORT_EMAIL_ID,$HELPDESK_SUPPORT_NAME;
$log =& LoggerManager::getLogger('SendSupportNotification');
$log = Logger::getLogger('SendSupportNotification');
$log->debug(" invoked SendSupportNotification ");
// retrieve the translated strings.
......
{
"name": "vtiger/vtigercrm",
"description": "Vtiger CRM",
"type": "project",
"license": "VPL",
"authors": [
{
"name": "Vtiger",
"email": "info@vtiger.com"
}
],
"autoload": {
"files": ["includes/Loader.php"]
},
"minimum-stability": "stable",
"require": {
"php": ">=8.1",
"ext-mysqli": "*",
"ext-imap": "*",
"ext-curl": "*",
"smarty/smarty": "^4.3",
"dg/rss-php": "^1.5",
"ezyang/htmlpurifier": "^4.16",
"tecnickcom/tcpdf": "^6.6",
"monolog/monolog": "^3.5",
"league/oauth2-client": "^2.7",
"phpmailer/phpmailer": "^6.9",
"league/oauth2-google": "^4.0"
}
}
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "fa2f0ab0051fb34dffffd5479695e9d4",
"packages": [
{
"name": "dg/rss-php",
"version": "v1.5",
"source": {
"type": "git",
"url": "https://github.com/dg/rss-php.git",
"reference": "18f00ab1828948a8cfe107729ca1f11c20129b47"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dg/rss-php/zipball/18f00ab1828948a8cfe107729ca1f11c20129b47",
"reference": "18f00ab1828948a8cfe107729ca1f11c20129b47",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"php": ">=5.3"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
}
],
"description": "RSS & Atom Feeds for PHP is a very small and easy-to-use library for consuming an RSS and Atom feed",
"homepage": "https://github.com/dg/rss-php",
"keywords": [
"atom",
"feed",
"rss"
],
"support": {
"source": "https://github.com/dg/rss-php/tree/v1.5"
},
"time": "2020-11-25T22:57:16+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.17.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/bbc513d79acf6691fa9cf10f192c90dd2957f18c",
"reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c",
"shasum": ""
},
"require": {
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",
"simpletest/simpletest": "dev-master"
},
"suggest": {
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
"ext-bcmath": "Used for unit conversion and imagecrash protection",
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
"ext-tidy": "Used for pretty-printing HTML"
},
"type": "library",
"autoload": {
"files": [
"library/HTMLPurifier.composer.php"
],
"psr-0": {
"HTMLPurifier": "library/"
},
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-or-later"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "admin@htmlpurifier.org",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/ezyang/htmlpurifier/issues",
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.17.0"
},
"time": "2023-11-17T15:01:25+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "7.9.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "d281ed313b989f213357e3be1a179f02196ac99b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b",
"reference": "d281ed313b989f213357e3be1a179f02196ac99b",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
"guzzlehttp/psr7": "^2.7.0",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"provide": {
"psr/http-client-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
"guzzle/client-integration-tests": "3.0.2",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.39 || ^9.6.20",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {
"ext-curl": "Required for CURL handler support",
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Jeremy Lindblom",
"email": "jeremeamia@gmail.com",
"homepage": "https://github.com/jeremeamia"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
}
],
"description": "Guzzle is a PHP HTTP client library",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"psr-18",
"psr-7",
"rest",
"web service"
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.9.2"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
"type": "tidelift"
}
],
"time": "2024-07-24T11:22:20+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8",
"reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/2.0.3"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
"type": "tidelift"
}
],
"time": "2024-07-18T10:29:17+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "2.7.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
"reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.1 || ^2.0",
"ralouphie/getallheaders": "^3.0"
},
"provide": {
"psr/http-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "0.9.0",
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://sagikazarmark.hu"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.7.0"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
"type": "tidelift"
}
],
"time": "2024-07-18T11:15:46+00:00"
},
{
"name": "league/oauth2-client",
"version": "2.7.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/oauth2-client.git",
"reference": "160d6274b03562ebeb55ed18399281d8118b76c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/160d6274b03562ebeb55ed18399281d8118b76c8",
"reference": "160d6274b03562ebeb55ed18399281d8118b76c8",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0 || ^7.0",
"paragonie/random_compat": "^1 || ^2 || ^9.99",
"php": "^5.6 || ^7.0 || ^8.0"
},
"require-dev": {
"mockery/mockery": "^1.3.5",
"php-parallel-lint/php-parallel-lint": "^1.3.1",
"phpunit/phpunit": "^5.7 || ^6.0 || ^9.5",
"squizlabs/php_codesniffer": "^2.3 || ^3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-2.x": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"League\\OAuth2\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alex Bilbie",
"email": "hello@alexbilbie.com",
"homepage": "http://www.alexbilbie.com",
"role": "Developer"
},
{
"name": "Woody Gilk",
"homepage": "https://github.com/shadowhand",
"role": "Contributor"
}
],
"description": "OAuth 2.0 Client Library",
"keywords": [
"Authentication",
"SSO",
"authorization",
"identity",
"idp",
"oauth",
"oauth2",
"single sign on"
],
"support": {
"issues": "https://github.com/thephpleague/oauth2-client/issues",
"source": "https://github.com/thephpleague/oauth2-client/tree/2.7.0"
},
"time": "2023-04-16T18:19:15+00:00"
},
{
"name": "league/oauth2-google",
"version": "4.0.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/oauth2-google.git",
"reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/1b01ba18ba31b29e88771e3e0979e5c91d4afe76",
"reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76",
"shasum": ""
},
"require": {
"league/oauth2-client": "^2.0",
"php": "^7.3 || ^8.0"
},
"require-dev": {
"eloquent/phony-phpunit": "^6.0 || ^7.1",
"phpunit/phpunit": "^8.0 || ^9.0",
"squizlabs/php_codesniffer": "^3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"League\\OAuth2\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Woody Gilk",
"email": "hello@shadowhand.com",
"homepage": "https://shadowhand.com"
}
],
"description": "Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client",
"keywords": [
"Authentication",
"authorization",
"client",
"google",
"oauth",
"oauth2"
],
"support": {
"issues": "https://github.com/thephpleague/oauth2-google/issues",
"source": "https://github.com/thephpleague/oauth2-google/tree/4.0.1"
},
"time": "2023-03-17T15:20:52+00:00"
},
{
"name": "monolog/monolog",
"version": "3.7.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8",
"reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^2.0 || ^3.0"
},
"provide": {
"psr/log-implementation": "3.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^3.0",
"doctrine/couchdb": "~1.0@dev",
"elasticsearch/elasticsearch": "^7 || ^8",
"ext-json": "*",
"graylog2/gelf-php": "^1.4.2 || ^2.0",
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"phpstan/phpstan": "^1.9",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-strict-rules": "^1.4",
"phpunit/phpunit": "^10.5.17",
"predis/predis": "^1.1 || ^2",
"ruflin/elastica": "^7",
"symfony/mailer": "^5.4 || ^6",
"symfony/mime": "^5.4 || ^6"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
"ext-mbstring": "Allow to work properly with unicode symbols",
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
"ext-openssl": "Required to send log messages using SSL",
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "https://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "https://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/3.7.0"
},
"funding": [
{
"url": "https://github.com/Seldaek",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
"type": "tidelift"
}
],
"time": "2024-06-28T09:40:51+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v9.99.100",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
"reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
"shasum": ""
},
"require": {
"php": ">= 7"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*",
"vimeo/psalm": "^1"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"polyfill",
"pseudorandom",
"random"
],
"support": {
"email": "info@paragonie.com",
"issues": "https://github.com/paragonie/random_compat/issues",
"source": "https://github.com/paragonie/random_compat"
},
"time": "2020-10-15T08:29:30+00:00"
},
{
"name": "phpmailer/phpmailer",
"version": "v6.9.1",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18",
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-filter": "*",
"ext-hash": "*",
"php": ">=5.5.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-only"
],
"authors": [
{
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
},
{
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
},
{
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
},
{
"name": "Brent R. Matzelle"
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1"
},
"funding": [
{
"url": "https://github.com/Synchro",
"type": "github"
}
],
"time": "2023-11-25T22:23:28+00:00"
},
{
"name": "psr/http-client",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-client.git",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP clients",
"homepage": "https://github.com/php-fig/http-client",
"keywords": [
"http",
"http-client",
"psr",
"psr-18"
],
"support": {
"source": "https://github.com/php-fig/http-client"
},
"time": "2023-09-23T14:17:50+00:00"
},
{
"name": "psr/http-factory",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-factory.git",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
"shasum": ""
},
"require": {
"php": ">=7.1",
"psr/http-message": "^1.0 || ^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-factory"
},
"time": "2024-04-15T12:06:14+00:00"
},
{
"name": "psr/http-message",
"version": "2.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"support": {
"source": "https://github.com/php-fig/http-message/tree/2.0"
},
"time": "2023-04-04T09:54:51+00:00"
},
{
"name": "psr/log",
"version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/3.0.2"
},
"time": "2024-09-11T13:17:53+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"support": {
"issues": "https://github.com/ralouphie/getallheaders/issues",
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "smarty/smarty",
"version": "v4.5.4",
"source": {
"type": "git",
"url": "https://github.com/smarty-php/smarty.git",
"reference": "c11676e85aa71bc7c3cd9100f1655a9f4d14616e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/c11676e85aa71bc7c3cd9100f1655a9f4d14616e",
"reference": "c11676e85aa71bc7c3cd9100f1655a9f4d14616e",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^8.5 || ^7.5",
"smarty/smarty-lexer": "^3.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
}
},
"autoload": {
"classmap": [
"libs/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Monte Ohrt",
"email": "monte@ohrt.com"
},
{
"name": "Uwe Tews",
"email": "uwe.tews@googlemail.com"
},
{
"name": "Rodney Rehm",
"email": "rodney.rehm@medialize.de"
},
{
"name": "Simon Wisselink",
"homepage": "https://www.iwink.nl/"
}
],
"description": "Smarty - the compiling PHP template engine",
"homepage": "https://smarty-php.github.io/smarty/",
"keywords": [
"templating"
],
"support": {
"forum": "https://github.com/smarty-php/smarty/discussions",
"issues": "https://github.com/smarty-php/smarty/issues",
"source": "https://github.com/smarty-php/smarty/tree/v4.5.4"
},
"time": "2024-08-14T20:04:35+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-04-18T09:32:20+00:00"
},
{
"name": "tecnickcom/tcpdf",
"version": "6.7.5",
"source": {
"type": "git",
"url": "https://github.com/tecnickcom/TCPDF.git",
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
"reference": "951eabf0338ec2522bd0d5d9c79b08a3a3d36b36",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"type": "library",
"autoload": {
"classmap": [
"config",
"include",
"tcpdf.php",
"tcpdf_parser.php",
"tcpdf_import.php",
"tcpdf_barcodes_1d.php",
"tcpdf_barcodes_2d.php",
"include/tcpdf_colors.php",
"include/tcpdf_filters.php",
"include/tcpdf_font_data.php",
"include/tcpdf_fonts.php",
"include/tcpdf_images.php",
"include/tcpdf_static.php",
"include/barcodes/datamatrix.php",
"include/barcodes/pdf417.php",
"include/barcodes/qrcode.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0-or-later"
],
"authors": [
{
"name": "Nicola Asuni",
"email": "info@tecnick.com",
"role": "lead"
}
],
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
"homepage": "http://www.tcpdf.org/",
"keywords": [
"PDFD32000-2008",
"TCPDF",
"barcodes",
"datamatrix",
"pdf",
"pdf417",
"qrcode"
],
"support": {
"issues": "https://github.com/tecnickcom/TCPDF/issues",
"source": "https://github.com/tecnickcom/TCPDF/tree/6.7.5"
},
"funding": [
{
"url": "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20tcpdf%20project",
"type": "custom"
}
],
"time": "2024-04-20T17:25:10+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=8.1",
"ext-mysqli": "*",
"ext-imap": "*",
"ext-curl": "*"
},
"platform-dev": [],
"plugin-api-version": "2.2.0"
}
......@@ -9,8 +9,8 @@
************************************************************************************/
/* Performance paramters can be configured to fine tune vtiger CRM runtime */
$PERFORMANCE_CONFIG = Array(
// Enable log4php debugging only if requried
'LOG4PHP_DEBUG' => false,
// Enable Vtiger Log Level for debugging only if requried
'LOGLEVEL_DEBUG' => false,
// Should the caller information be captured in SQL Logging?
// It adds little overhead for performance but will be useful to debug
......
......@@ -22,6 +22,11 @@ include('config.inc.php');
$THIS_DIR = dirname(__FILE__);
/* Pre-install overrides */
if (!isset($dbconfig)) {
error_reporting(E_ERROR & ~E_NOTICE & ~E_DEPRECATED);
}
if (file_exists($THIS_DIR.'/config_override.php')) {
include_once $THIS_DIR.'/config_override.php';
}
......@@ -30,15 +35,15 @@ class VtigerConfig {
static function get($key, $defvalue='') {
if (self::has($key)) {
global $$key;
return $$key;
global ${$key};
return ${$key};
}
return $defvalue;
}
static function has($key) {
global $$key;
return (isset($$key));
global ${$key};
return (isset(${$key}));
}
static function getOD($key, $defvalue='') {
......
......@@ -111,7 +111,7 @@ $allow_exports = 'all';
// files with one of these extensions will have '.txt' appended to their filename on upload
// upload_badext default value = php, php3, php4, php5, pl, cgi, py, asp, cfm, js, vbs, html, htm
$upload_badext = array('php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py', 'asp', 'cfm', 'js', 'vbs', 'html', 'htm', 'exe', 'bin', 'bat', 'sh', 'dll', 'phps', 'phtml', 'xhtml', 'rb', 'msi', 'jsp', 'shtml', 'sth', 'shtm');
$upload_badext = array('php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py', 'asp', 'cfm', 'js', 'vbs', 'html', 'htm', 'exe', 'bin', 'bat', 'sh', 'dll', 'phps', 'phtml', 'xhtml', 'rb', 'msi', 'jsp', 'shtml', 'sth', 'shtm', 'htaccess', 'phar');
// list_max_entries_per_page default value = 20
$list_max_entries_per_page = '20';
......@@ -119,9 +119,6 @@ $list_max_entries_per_page = '20';
// history_max_viewed default value = 5
$history_max_viewed = '5';
// default_module default value = Home
$default_module = 'Home';
// default_action default value = index
$default_action = 'index';
......@@ -178,5 +175,8 @@ if(isset($default_timezone) && function_exists('date_default_timezone_set')) {
//Set the default layout
$default_layout = 'v7';
//Maximum Listview Fields Selection Size
$maxListFieldsSelectionSize = 15;
include_once 'config.security.php';
?>
<?php
/** Logging configuration for Strict Development */
require_once "vtlib/Vtiger/Utils/PhpLogHandler.php";
Vtiger_PhpLogHandler::enableStrictLogging(__DIR__, "logs/phperr.log");
......@@ -10,3 +10,14 @@
//Maximum number of Mailboxes in mail converter
$max_mailboxes = 3;
/**
* Configure runtime connectors to customization in core files.
* Ex: Sessions are currently handled by PHP default session handler.
* This can be customized using runtime connector hook and avoid core file modifications.
* array('session' => 'Vtiger_CustomSession_Handler')
*/
$runtime_connectors = array();
//Password Regex for validation
$validation_regex = array('password_regex' => '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})');
\ No newline at end of file
deny from all
......@@ -22,7 +22,8 @@
//file modified by richie
require_once('include/utils/utils.php');
require_once("modules/Emails/class.phpmailer.php");
//require_once("modules/Emails/class.smtp.php");
//require_once("modules/Emails/class.phpmailer.php");
require_once("modules/Emails/mail.php");
require_once('include/logging.php');
require_once("config.php");
......@@ -41,7 +42,7 @@ if(empty($from)) {
global $adb;
global $log;
global $site_URL;
$log =& LoggerManager::getLogger('SendReminder');
$log =Logger::getLogger('SendReminder');
$log->debug(" invoked SendReminder ");
// retrieve the translated strings.
......@@ -51,14 +52,14 @@ $app_strings = return_application_language($current_language);
//modified query for recurring events -Jag
$query="SELECT vtiger_crmentity.crmid, vtiger_crmentity.description, vtiger_crmentity.smownerid, vtiger_seactivityrel.crmid AS setype,vtiger_activity.*,vtiger_activity_reminder.reminder_time,
vtiger_activity_reminder.reminder_sent,vtiger_activity_reminder.recurringid FROM vtiger_activity
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid=vtiger_activity.activityid
INNER JOIN vtiger_activity_reminder ON vtiger_activity.activityid=vtiger_activity_reminder.activity_id
LEFT OUTER JOIN vtiger_seactivityrel ON vtiger_seactivityrel.activityid = vtiger_activity.activityid
WHERE DATE_FORMAT(vtiger_activity.date_start,'%Y-%m-%d, %H:%i:%s') >= '".date('Y-m-d')."' AND vtiger_crmentity.crmid != 0 AND
(vtiger_activity.eventstatus is NULL OR vtiger_activity.eventstatus NOT IN ('Held','Cancelled'))
vtiger_activity_reminder.reminder_sent,vtiger_activity_reminder.recurringid FROM vtiger_activity
INNER JOIN vtiger_crmentity ON vtiger_crmentity.crmid=vtiger_activity.activityid
INNER JOIN vtiger_activity_reminder ON vtiger_activity.activityid=vtiger_activity_reminder.activity_id
LEFT OUTER JOIN vtiger_seactivityrel ON vtiger_seactivityrel.activityid = vtiger_activity.activityid
WHERE DATE_FORMAT(vtiger_activity.date_start,'%Y-%m-%d, %H:%i:%s') >= '".date('Y-m-d')."' AND vtiger_crmentity.crmid != 0 AND
(vtiger_activity.eventstatus is NULL OR vtiger_activity.eventstatus NOT IN ('Held','Cancelled'))
AND (vtiger_activity.status is NULL OR vtiger_activity.status NOT IN ('Completed', 'Deferred', 'Cancelled'))
AND vtiger_activity_reminder.reminder_sent = 0 AND vtiger_activity_reminder.reminder_time != 0
AND vtiger_activity_reminder.reminder_sent = 0 AND vtiger_activity_reminder.reminder_time != 0
GROUP BY vtiger_activity.activityid";
$result = $adb->pquery($query, array());
......@@ -93,7 +94,7 @@ if($adb->num_rows($result) >= 1)
$activitymode = ($result_set['activitytype'] == "Task")?"Task":"Events";
$parent_type = $result_set['setype'];
$activity_sub = $result_set['subject'];
$to_addr='';
$to_addr= array();
if($parent_type!='')
$parent_content = getParentInfo($parent_type)."\n";
......@@ -170,7 +171,7 @@ if($adb->num_rows($result) >= 1)
$result_set['subject'] = decode_html($result_set['subject']);
if($result_set['activitytype'] == "Task") {
$enddateInOwnerFormat = $enddateTime->getDisplayDate($ownerFocus);
$list = $todoReminderBody;
$list = $todoReminderBody;
$list = str_replace('$calendar-subject$',$result_set['subject'],$list);
$list = str_replace('$calendar-description$',$result_set['description'],$list);
$list = str_replace('$calendar-date_start$', $dateTimeInOwnerFormat.' '.$ownerTimeZone, $list);
......@@ -193,11 +194,11 @@ if($adb->num_rows($result) >= 1)
$recordModel = Vtiger_Record_Model::getInstanceById($activity_id, 'Calendar');
$recordDetailViewLink = $recordModel->getDetailViewUrl();
$contents = $contents."<br/> ".vtranslate('LBL_CLICK_HERE_TO_VIEW', 'Calendar')."&nbsp;<a href=$site_URL/$recordDetailViewLink>".vtranslate('LBL_RECORD', 'Calendar')."</a>";
if(count($to_addr) >=1)
if(php7_count($to_addr) >=1)
{
send_email($to_addr,$from,$subject,$contents,$mail_server,$mail_server_username,$mail_server_password);
$upd_query = "UPDATE vtiger_activity_reminder SET reminder_sent = ?";
$upd_params = array(1);
$upd_query = "UPDATE vtiger_activity_reminder SET reminder_sent = ? WHERE activity_id = ?";
$upd_params = array('1',$activity_id);
if($recur_id!=0)
{
......@@ -231,7 +232,7 @@ function send_email($to,$from,$subject,$contents,$mail_server,$mail_server_usern
$log->info("This is send_mail function in SendReminder.php(vtiger home).");
global $root_directory;
$mail = new PHPMailer();
$mail = new PHPMailer\PHPMailer\PHPMailer();
$mail->Subject = $subject;
......@@ -253,7 +254,7 @@ function send_email($to,$from,$subject,$contents,$mail_server,$mail_server_usern
else
$mail->SMTPAuth = false;
$mail->Username = $mail_server_username ; // SMTP username
$mail->Password = $mail_server_password ; // SMTP password
$mail->Password = Vtiger_Functions::fromProtectedText($mail_server_password) ; // SMTP password
$mail->From = $from;
$mail->FromName = $initialfrom;
$log->info("Mail sending process : From Name & email id => '".$initialfrom."','".$from."'");
......
<?php
////////////////////////////////////////////////////
// PHPMailer - PHP email class
//
// Class for sending email using either
// sendmail, PHP mail(), or SMTP. Methods are
// based upon the standard AspEmail(tm) classes.
//
// Copyright (C) 2001 - 2003 Brent R. Matzelle
//
// License: LGPL, see LICENSE
////////////////////////////////////////////////////
/**
* PHPMailer - PHP email transport class
* @package PHPMailer
* @author Brent R. Matzelle
* @copyright 2001 - 2003 Brent R. Matzelle
*/
class PHPMailer
{
/////////////////////////////////////////////////
// PUBLIC VARIABLES
/////////////////////////////////////////////////
/**
* Email priority (1 = High, 3 = Normal, 5 = low).
* @var int
*/
var $Priority = 3;
/**
* Sets the CharSet of the message.
* @var string
*/
var $CharSet = "UTF-8";
/**
* Sets the Content-type of the message.
* @var string
*/
var $ContentType = "text/plain";
/**
* Sets the Encoding of the message. Options for this are "8bit",
* "7bit", "binary", "base64", and "quoted-printable".
* @var string
*/
var $Encoding = "8bit";
/**
* Holds the most recent mailer error message.
* @var string
*/
var $ErrorInfo = "";
/**
* Sets the From email address for the message.
* @var string
*/
var $From = "root@localhost";
/**
* Sets the From name of the message.
* @var string
*/
var $FromName = "Root User";
/**
* Sets the Sender email (Return-Path) of the message. If not empty,
* will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
* @var string
*/
var $Sender = "";
/**
* Sets the Subject of the message.
* @var string
*/
var $Subject = "";
/**
* Sets the Body of the message. This can be either an HTML or text body.
* If HTML then run IsHTML(true).
* @var string
*/
var $Body = "";
/**
* Sets the text-only body of the message. This automatically sets the
* email to multipart/alternative. This body can be read by mail
* clients that do not have HTML email capability such as mutt. Clients
* that can read HTML will view the normal Body.
* @var string
*/
var $AltBody = "";
/**
* Sets word wrapping on the body of the message to a given number of
* characters.
* @var int
*/
var $WordWrap = 0;
/**
* Method to send mail: ("mail", "sendmail", or "smtp").
* @var string
*/
var $Mailer = "mail";
/**
* Sets the path of the sendmail program.
* @var string
*/
var $Sendmail = "/usr/sbin/sendmail";
/**
* Path to PHPMailer plugins. This is now only useful if the SMTP class
* is in a different directory than the PHP include path.
* @var string
*/
var $PluginDir = "";
/**
* Holds PHPMailer version.
* @var string
*/
var $Version = "1.72";
/**
* Sets the email address that a reading confirmation will be sent.
* @var string
*/
var $ConfirmReadingTo = "";
/**
* Sets the hostname to use in Message-Id and Received headers
* and as default HELO string. If empty, the value returned
* by SERVER_NAME is used or 'localhost.localdomain'.
* @var string
*/
var $Hostname = "";
/////////////////////////////////////////////////
// SMTP VARIABLES
/////////////////////////////////////////////////
/**
* Sets the SMTP hosts. All hosts must be separated by a
* semicolon. You can also specify a different port
* for each host by using this format: [hostname:port]
* (e.g. "smtp1.example.com:25;smtp2.example.com").
* Hosts will be tried in order.
* @var string
*/
var $Host = "localhost";
/**
* Sets the default SMTP server port.
* @var int
*/
var $Port = 25;
/**
* Sets the SMTP HELO of the message (Default is $Hostname).
* @var string
*/
var $Helo = "";
/**
* Sets SMTP authentication. Utilizes the Username and Password variables.
* @var bool
*/
var $SMTPAuth = false;
/**
* Sets SMTP username.
* @var string
*/
var $Username = "";
/**
* Sets SMTP password.
* @var string
*/
var $Password = "";
/**
* Sets the SMTP server timeout in seconds. This function will not
* work with the win32 version.
* @var int
*/
var $Timeout = 60; // Fix for http://trac.vtiger.com/cgi-bin/trac.cgi/ticket/5389
/**
* Sets SMTP class debugging on or off.
* @var bool
*/
var $SMTPDebug = false;
/**
* Prevents the SMTP connection from being closed after each mail
* sending. If this is set to true then to close the connection
* requires an explicit call to SmtpClose().
* @var bool
*/
var $SMTPKeepAlive = false;
/**#@+
* @access private
*/
var $smtp = NULL;
var $to = array();
var $cc = array();
var $bcc = array();
var $ReplyTo = array();
var $attachment = array();
var $CustomHeader = array();
var $message_type = "";
var $boundary = array();
var $language = array();
var $error_count = 0;
var $LE = "\n";
/**#@-*/
/////////////////////////////////////////////////
// VARIABLE METHODS
/////////////////////////////////////////////////
/**
* Sets message type to HTML.
* @param bool $bool
* @return void
*/
function IsHTML($bool) {
if($bool == true)
$this->ContentType = "text/html";
else
$this->ContentType = "text/plain";
}
/**
* Sets Mailer to send message using SMTP.
* @return void
*/
function IsSMTP() {
$this->Mailer = "smtp";
}
/**
* Sets Mailer to send message using PHP mail() function.
* @return void
*/
function IsMail() {
$this->Mailer = "mail";
}
/**
* Sets Mailer to send message using the $Sendmail program.
* @return void
*/
function IsSendmail() {
$this->Mailer = "sendmail";
}
/**
* Sets Mailer to send message using the qmail MTA.
* @return void
*/
function IsQmail() {
$this->Sendmail = "/var/qmail/bin/sendmail";
$this->Mailer = "sendmail";
}
/////////////////////////////////////////////////
// RECIPIENT METHODS
/////////////////////////////////////////////////
/**
* Adds a "To" address.
* @param string $address
* @param string $name
* @return void
*/
function AddAddress($address, $name = "") {
$cur = count($this->to);
$this->to[$cur][0] = trim($address);
$this->to[$cur][1] = $name;
}
/**
* Adds a "Cc" address. Note: this function works
* with the SMTP mailer on win32, not with the "mail"
* mailer.
* @param string $address
* @param string $name
* @return void
*/
function AddCC($address, $name = "") {
$cur = count($this->cc);
$this->cc[$cur][0] = trim($address);
$this->cc[$cur][1] = $name;
}
/**
* Adds a "Bcc" address. Note: this function works
* with the SMTP mailer on win32, not with the "mail"
* mailer.
* @param string $address
* @param string $name
* @return void
*/
function AddBCC($address, $name = "") {
$cur = count($this->bcc);
$this->bcc[$cur][0] = trim($address);
$this->bcc[$cur][1] = $name;
}
/**
* Adds a "Reply-to" address.
* @param string $address
* @param string $name
* @return void
*/
function AddReplyTo($address, $name = "") {
$cur = count($this->ReplyTo);
$this->ReplyTo[$cur][0] = trim($address);
$this->ReplyTo[$cur][1] = $name;
}
/////////////////////////////////////////////////
// MAIL SENDING METHODS
/////////////////////////////////////////////////
/**
* Creates message and assigns Mailer. If the message is
* not sent successfully then it returns false. Use the ErrorInfo
* variable to view description of the error.
* @return bool
*/
function Send() {
$header = "";
$body = "";
$result = true;
if((count($this->to) + count($this->cc) + count($this->bcc)) < 1)
{
$this->SetError($this->Lang("provide_address"));
return false;
}
// Set whether the message is multipart/alternative
if(!empty($this->AltBody))
$this->ContentType = "multipart/alternative";
$this->error_count = 0; // reset errors
$this->SetMessageType();
$header .= $this->CreateHeader();
$body = $this->CreateBody();
if($body == "") { return false; }
// Choose the mailer
switch($this->Mailer)
{
case "sendmail":
$result = $this->SendmailSend($header, $body);
break;
case "mail":
$result = $this->MailSend($header, $body);
break;
case "smtp":
$result = $this->SmtpSend($header, $body);
break;
default:
$this->SetError($this->Mailer . $this->Lang("mailer_not_supported"));
$result = false;
break;
}
return $result;
}
/**
* Sends mail using the $Sendmail program.
* @access private
* @return bool
*/
function SendmailSend($header, $body) {
if ($this->Sender != "")
$sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellcmd($this->Sender));
else
$sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
if(!@$mail = popen($sendmail, "w"))
{
$this->SetError($this->Lang("execute") . $this->Sendmail);
return false;
}
fputs($mail, $header);
fputs($mail, $body);
$result = pclose($mail) >> 8 & 0xFF;
if($result != 0)
{
$this->SetError($this->Lang("execute") . $this->Sendmail);
return false;
}
return true;
}
/**
* Sends mail using the PHP mail() function.
* @access private
* @return bool
*/
function MailSend($header, $body) {
$to = "";
for($i = 0; $i < count($this->to); $i++)
{
if($i != 0) { $to .= ", "; }
$to .= $this->to[$i][0];
}
if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1)
{
$old_from = ini_get("sendmail_from");
ini_set("sendmail_from", $this->Sender);
$params = sprintf("-oi -f %s", $this->Sender);
$rt = @mail($to, $this->EncodeHeader($this->Subject), $body,
$header, $params);
}
else
$rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header);
if (isset($old_from))
ini_set("sendmail_from", $old_from);
if(!$rt)
{
$this->SetError($this->Lang("instantiate"));
return false;
}
return true;
}
/**
* Sends mail via SMTP using PhpSMTP (Author:
* Chris Ryan). Returns bool. Returns false if there is a
* bad MAIL FROM, RCPT, or DATA input.
* @access private
* @return bool
*/
function SmtpSend($header, $body) {
include_once($this->PluginDir . "class.smtp.php");
$error = "";
$bad_rcpt = array();
if(!$this->SmtpConnect())
return false;
$smtp_from = ($this->Sender == "") ? $this->From : $this->Sender;
if(!$this->smtp->Mail($smtp_from))
{
$error = $this->Lang("from_failed") . $smtp_from;
$this->SetError($error);
$this->smtp->Reset();
return false;
}
// Attempt to send attach all recipients
for($i = 0; $i < count($this->to); $i++)
{
if(!$this->smtp->Recipient($this->to[$i][0]))
$bad_rcpt[] = $this->to[$i][0];
}
for($i = 0; $i < count($this->cc); $i++)
{
if(!$this->smtp->Recipient($this->cc[$i][0]))
$bad_rcpt[] = $this->cc[$i][0];
}
for($i = 0; $i < count($this->bcc); $i++)
{
if(!$this->smtp->Recipient($this->bcc[$i][0]))
$bad_rcpt[] = $this->bcc[$i][0];
}
if(count($bad_rcpt) > 0) // Create error message
{
for($i = 0; $i < count($bad_rcpt); $i++)
{
if($i != 0) { $error .= ", "; }
$error .= $bad_rcpt[$i];
}
$error = $this->Lang("recipients_failed") . $error;
$this->SetError($error);
$this->smtp->Reset();
return false;
}
if(!$this->smtp->Data($header . $body))
{
$this->SetError($this->Lang("data_not_accepted"));
$this->smtp->Reset();
return false;
}
if($this->SMTPKeepAlive == true)
$this->smtp->Reset();
else
$this->SmtpClose();
return true;
}
/**
* Initiates a connection to an SMTP server. Returns false if the
* operation failed.
* @access private
* @return bool
*/
function SmtpConnect() {
if($this->smtp == NULL) { $this->smtp = new SMTP(); }
$this->smtp->do_debug = $this->SMTPDebug;
$hosts = explode(";", $this->Host);
$index = 0;
$connection = ($this->smtp->Connected());
// Retry while there is no connection
while($index < count($hosts) && $connection == false)
{
if(strstr($hosts[$index], ":"))
{
#list($host, $port) = explode(":", $hosts[$index]);
// Prasad: support for host's like ssl://smtp.gmail.com:465
$hostA = explode(':', $hosts[$index]);
if (is_numeric(end($hostA)))
$port = array_pop($hostA);
else
$port = $this->Port;
$host = implode(':', $hostA);
}
else
{
$host = $hosts[$index];
$port = $this->Port;
}
if($this->smtp->Connect($host, $port, $this->Timeout))
{
if ($this->Helo != '')
$this->smtp->Hello($this->Helo);
else
$this->smtp->Hello($this->ServerHostname());
if($this->SMTPAuth)
{
if(!$this->smtp->Authenticate($this->Username,
$this->Password))
{
$this->SetError($this->Lang("authenticate"));
$this->smtp->Reset();
$connection = false;
}
}
$connection = true;
}
$index++;
}
if(!$connection)
$this->SetError($this->Lang("connect_host"));
return $connection;
}
/**
* Closes the active SMTP session if one exists.
* @return void
*/
function SmtpClose() {
if($this->smtp != NULL)
{
if($this->smtp->Connected())
{
$this->smtp->Quit();
$this->smtp->Close();
}
}
}
/**
* Sets the language for all class error messages. Returns false
* if it cannot load the language file. The default language type
* is English.
* @param string $lang_type Type of language (e.g. Portuguese: "br")
* @param string $lang_path Path to the language file directory
* @access public
* @return bool
*/
function SetLanguage($lang_type, $lang_path = "language/") {
global $root_directory;
if(file_exists($root_directory.'/cron/'.$lang_path.'phpmailer.lang-'.$lang_type.'.php'))
include($root_directory.'/cron/'.$lang_path.'phpmailer.lang-'.$lang_type.'.php');
else if($root_directory.'/cron/'.file_exists($lang_path.'phpmailer.lang-en.php'))
include($root_directory.'/cron/'.$lang_path.'phpmailer.lang-en.php');
else
{
$this->SetError("Could not load language file");
return false;
}
$this->language = $PHPMAILER_LANG;
return true;
}
/////////////////////////////////////////////////
// MESSAGE CREATION METHODS
/////////////////////////////////////////////////
/**
* Creates recipient headers.
* @access private
* @return string
*/
function AddrAppend($type, $addr) {
$addr_str = $type . ": ";
$addr_str .= $this->AddrFormat($addr[0]);
if(count($addr) > 1)
{
for($i = 1; $i < count($addr); $i++)
$addr_str .= ", " . $this->AddrFormat($addr[$i]);
}
$addr_str .= $this->LE;
return $addr_str;
}
/**
* Formats an address correctly.
* @access private
* @return string
*/
function AddrFormat($addr) {
if(empty($addr[1]))
$formatted = $addr[0];
else
{
$formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" .
$addr[0] . ">";
}
return $formatted;
}
/**
* Wraps message for use with mailers that do not
* automatically perform wrapping and for quoted-printable.
* Original written by philippe.
* @access private
* @return string
*/
function WrapText($message, $length, $qp_mode = false) {
$soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
$message = $this->FixEOL($message);
if (substr($message, -1) == $this->LE)
$message = substr($message, 0, -1);
$line = explode($this->LE, $message);
$message = "";
for ($i=0 ;$i < count($line); $i++)
{
$line_part = explode(" ", $line[$i]);
$buf = "";
for ($e = 0; $e<count($line_part); $e++)
{
$word = $line_part[$e];
if ($qp_mode and (strlen($word) > $length))
{
$space_left = $length - strlen($buf) - 1;
if ($e != 0)
{
if ($space_left > 20)
{
$len = $space_left;
if (substr($word, $len - 1, 1) == "=")
$len--;
elseif (substr($word, $len - 2, 1) == "=")
$len -= 2;
$part = substr($word, 0, $len);
$word = substr($word, $len);
$buf .= " " . $part;
$message .= $buf . sprintf("=%s", $this->LE);
}
else
{
$message .= $buf . $soft_break;
}
$buf = "";
}
while (strlen($word) > 0)
{
$len = $length;
if (substr($word, $len - 1, 1) == "=")
$len--;
elseif (substr($word, $len - 2, 1) == "=")
$len -= 2;
$part = substr($word, 0, $len);
$word = substr($word, $len);
if (strlen($word) > 0)
$message .= $part . sprintf("=%s", $this->LE);
else
$buf = $part;
}
}
else
{
$buf_o = $buf;
$buf .= ($e == 0) ? $word : (" " . $word);
if (strlen($buf) > $length and $buf_o != "")
{
$message .= $buf_o . $soft_break;
$buf = $word;
}
}
}
$message .= $buf . $this->LE;
}
return $message;
}
/**
* Set the body wrapping.
* @access private
* @return void
*/
function SetWordWrap() {
if($this->WordWrap < 1)
return;
switch($this->message_type)
{
case "alt":
// fall through
case "alt_attachment":
$this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
break;
default:
$this->Body = $this->WrapText($this->Body, $this->WordWrap);
break;
}
}
/**
* Assembles message header.
* @access private
* @return string
*/
function CreateHeader() {
$result = "";
// Set the boundaries
$uniq_id = md5(uniqid(time()));
$this->boundary[1] = "b1_" . $uniq_id;
$this->boundary[2] = "b2_" . $uniq_id;
$result .= $this->HeaderLine("Date", $this->RFCDate());
if($this->Sender == "")
$result .= $this->HeaderLine("Return-Path", trim($this->From));
else
$result .= $this->HeaderLine("Return-Path", trim($this->Sender));
// To be created automatically by mail()
if($this->Mailer != "mail")
{
if(count($this->to) > 0)
$result .= $this->AddrAppend("To", $this->to);
else if (count($this->cc) == 0)
$result .= $this->HeaderLine("To", "undisclosed-recipients:;");
if(count($this->cc) > 0)
$result .= $this->AddrAppend("Cc", $this->cc);
}
$from = array();
$from[0][0] = trim($this->From);
$from[0][1] = $this->FromName;
$result .= $this->AddrAppend("From", $from);
// sendmail and mail() extract Bcc from the header before sending
if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0))
$result .= $this->AddrAppend("Bcc", $this->bcc);
if(count($this->ReplyTo) > 0)
$result .= $this->AddrAppend("Reply-to", $this->ReplyTo);
// mail() sets the subject itself
if($this->Mailer != "mail")
$result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject)));
$result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
$result .= $this->HeaderLine("X-Priority", $this->Priority);
$result .= $this->HeaderLine("X-Mailer", "PHPMailer [version " . $this->Version . "]");
if($this->ConfirmReadingTo != "")
{
$result .= $this->HeaderLine("Disposition-Notification-To",
"<" . trim($this->ConfirmReadingTo) . ">");
}
// Add custom headers
for($index = 0; $index < count($this->CustomHeader); $index++)
{
$result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]),
$this->EncodeHeader(trim($this->CustomHeader[$index][1])));
}
$result .= $this->HeaderLine("MIME-Version", "1.0");
switch($this->message_type)
{
case "plain":
$result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding);
$result .= sprintf("Content-Type: %s; charset=\"%s\"",
$this->ContentType, $this->CharSet);
break;
case "attachments":
// fall through
case "alt_attachments":
if($this->InlineImageExists())
{
$result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s",
"multipart/related", $this->LE, $this->LE,
$this->boundary[1], $this->LE);
}
else
{
$result .= $this->HeaderLine("Content-Type", "multipart/mixed;");
$result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
}
break;
case "alt":
$result .= $this->HeaderLine("Content-Type", "multipart/alternative;");
$result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
break;
}
if($this->Mailer != "mail")
$result .= $this->LE.$this->LE;
return $result;
}
/**
* Assembles the message body. Returns an empty string on failure.
* @access private
* @return string
*/
function CreateBody() {
$result = "";
$this->SetWordWrap();
switch($this->message_type)
{
case "alt":
$result .= $this->GetBoundary($this->boundary[1], "",
"text/plain", "");
$result .= $this->EncodeString($this->AltBody, $this->Encoding);
$result .= $this->LE.$this->LE;
$result .= $this->GetBoundary($this->boundary[1], "",
"text/html", "");
$result .= $this->EncodeString($this->Body, $this->Encoding);
$result .= $this->LE.$this->LE;
$result .= $this->EndBoundary($this->boundary[1]);
break;
case "plain":
$result .= $this->EncodeString($this->Body, $this->Encoding);
break;
case "attachments":
$result .= $this->GetBoundary($this->boundary[1], "", "", "");
$result .= $this->EncodeString($this->Body, $this->Encoding);
$result .= $this->LE;
$result .= $this->AttachAll();
break;
case "alt_attachments":
$result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
$result .= sprintf("Content-Type: %s;%s" .
"\tboundary=\"%s\"%s",
"multipart/alternative", $this->LE,
$this->boundary[2], $this->LE.$this->LE);
// Create text body
$result .= $this->GetBoundary($this->boundary[2], "",
"text/plain", "") . $this->LE;
$result .= $this->EncodeString($this->AltBody, $this->Encoding);
$result .= $this->LE.$this->LE;
// Create the HTML body
$result .= $this->GetBoundary($this->boundary[2], "",
"text/html", "") . $this->LE;
$result .= $this->EncodeString($this->Body, $this->Encoding);
$result .= $this->LE.$this->LE;
$result .= $this->EndBoundary($this->boundary[2]);
$result .= $this->AttachAll();
break;
}
if($this->IsError())
$result = "";
return $result;
}
/**
* Returns the start of a message boundary.
* @access private
*/
function GetBoundary($boundary, $charSet, $contentType, $encoding) {
$result = "";
if($charSet == "") { $charSet = $this->CharSet; }
if($contentType == "") { $contentType = $this->ContentType; }
if($encoding == "") { $encoding = $this->Encoding; }
$result .= $this->TextLine("--" . $boundary);
$result .= sprintf("Content-Type: %s; charset = \"%s\"",
$contentType, $charSet);
$result .= $this->LE;
$result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding);
$result .= $this->LE;
return $result;
}
/**
* Returns the end of a message boundary.
* @access private
*/
function EndBoundary($boundary) {
return $this->LE . "--" . $boundary . "--" . $this->LE;
}
/**
* Sets the message type.
* @access private
* @return void
*/
function SetMessageType() {
if(count($this->attachment) < 1 && strlen($this->AltBody) < 1)
$this->message_type = "plain";
else
{
if(count($this->attachment) > 0)
$this->message_type = "attachments";
if(strlen($this->AltBody) > 0 && count($this->attachment) < 1)
$this->message_type = "alt";
if(strlen($this->AltBody) > 0 && count($this->attachment) > 0)
$this->message_type = "alt_attachments";
}
}
/**
* Returns a formatted header line.
* @access private
* @return string
*/
function HeaderLine($name, $value) {
return $name . ": " . $value . $this->LE;
}
/**
* Returns a formatted mail line.
* @access private
* @return string
*/
function TextLine($value) {
return $value . $this->LE;
}
/////////////////////////////////////////////////
// ATTACHMENT METHODS
/////////////////////////////////////////////////
/**
* Adds an attachment from a path on the filesystem.
* Returns false if the file could not be found
* or accessed.
* @param string $path Path to the attachment.
* @param string $name Overrides the attachment name.
* @param string $encoding File encoding (see $Encoding).
* @param string $type File extension (MIME) type.
* @return bool
*/
function AddAttachment($path, $name = "", $encoding = "base64",
$type = "application/octet-stream") {
if(!@is_file($path))
{
$this->SetError($this->Lang("file_access") . $path);
return false;
}
$filename = basename($path);
if($name == "")
$name = $filename;
$cur = count($this->attachment);
$this->attachment[$cur][0] = $path;
$this->attachment[$cur][1] = $filename;
$this->attachment[$cur][2] = $name;
$this->attachment[$cur][3] = $encoding;
$this->attachment[$cur][4] = $type;
$this->attachment[$cur][5] = false; // isStringAttachment
$this->attachment[$cur][6] = "attachment";
$this->attachment[$cur][7] = 0;
return true;
}
/**
* Attaches all fs, string, and binary attachments to the message.
* Returns an empty string on failure.
* @access private
* @return string
*/
function AttachAll() {
// Return text of body
$mime = array();
// Add all attachments
for($i = 0; $i < count($this->attachment); $i++)
{
// Check for string attachment
$bString = $this->attachment[$i][5];
if ($bString)
$string = $this->attachment[$i][0];
else
$path = $this->attachment[$i][0];
$filename = $this->attachment[$i][1];
$name = $this->attachment[$i][2];
$encoding = $this->attachment[$i][3];
$type = $this->attachment[$i][4];
$disposition = $this->attachment[$i][6];
$cid = $this->attachment[$i][7];
$mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
$mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
$mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
if($disposition == "inline")
$mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
$mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s",
$disposition, $name, $this->LE.$this->LE);
// Encode as string attachment
if($bString)
{
$mime[] = $this->EncodeString($string, $encoding);
if($this->IsError()) { return ""; }
$mime[] = $this->LE.$this->LE;
}
else
{
$mime[] = $this->EncodeFile($path, $encoding);
if($this->IsError()) { return ""; }
$mime[] = $this->LE.$this->LE;
}
}
$mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
return join("", $mime);
}
/**
* Encodes attachment in requested format. Returns an
* empty string on failure.
* @access private
* @return string
*/
function EncodeFile ($path, $encoding = "base64") {
if(!@$fd = fopen($path, "rb"))
{
$this->SetError($this->Lang("file_open") . $path);
return "";
}
if(!@$file_buffer = fread($fd, filesize($path)))
{
// $this->SetError($this->Lang("file_open") . $path);
// return "";
}
$file_buffer = $this->EncodeString($file_buffer, $encoding);
fclose($fd);
return $file_buffer;
}
/**
* Encodes string to requested format. Returns an
* empty string on failure.
* @access private
* @return string
*/
function EncodeString ($str, $encoding = "base64") {
$encoded = "";
switch(strtolower($encoding)) {
case "base64":
// chunk_split is found in PHP >= 3.0.6
$encoded = chunk_split(base64_encode($str), 76, $this->LE);
break;
case "7bit":
case "8bit":
$encoded = $this->FixEOL($str);
if (substr($encoded, -(strlen($this->LE))) != $this->LE)
$encoded .= $this->LE;
break;
case "binary":
$encoded = $str;
break;
case "quoted-printable":
$encoded = $this->EncodeQP($str);
break;
default:
$this->SetError($this->Lang("encoding") . $encoding);
break;
}
return $encoded;
}
/**
* Encode a header string to best of Q, B, quoted or none.
* @access private
* @return string
*/
function EncodeHeader ($str, $position = 'text') {
$x = 0;
switch (strtolower($position)) {
case 'phrase':
if (!preg_match('/[\200-\377]/', $str)) {
// Can't use addslashes as we don't know what value has magic_quotes_sybase.
$encoded = addcslashes($str, "\0..\37\177\\\"");
if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str))
return ($encoded);
else
return ("\"$encoded\"");
}
$x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
break;
case 'comment':
$x = preg_match_all('/[()"]/', $str, $matches);
// Fall-through
case 'text':
default:
$x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
break;
}
if ($x == 0)
return ($str);
$maxlen = 75 - 7 - strlen($this->CharSet);
// Try to select the encoding which should produce the shortest output
if (strlen($str)/3 < $x) {
$encoding = 'B';
$encoded = base64_encode($str);
$maxlen -= $maxlen % 4;
$encoded = trim(chunk_split($encoded, $maxlen, "\n"));
} else {
$encoding = 'Q';
$encoded = $this->EncodeQ($str, $position);
$encoded = $this->WrapText($encoded, $maxlen, true);
$encoded = str_replace("=".$this->LE, "\n", trim($encoded));
}
$encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
$encoded = trim(str_replace("\n", $this->LE, $encoded));
return $encoded;
}
/**
* Encode string to quoted-printable.
* @access private
* @return string
*/
function EncodeQP ($str) {
$encoded = $this->FixEOL($str);
if (substr($encoded, -(strlen($this->LE))) != $this->LE)
$encoded .= $this->LE;
// Replace every high ascii, control and = characters
$encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e',
"'='.sprintf('%02X', ord('\\1'))", $encoded);
// Replace every spaces and tabs when it's the last character on a line
$encoded = preg_replace("/([\011\040])".$this->LE."/e",
"'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded);
// Maximum line length of 76 characters before CRLF (74 + space + '=')
$encoded = $this->WrapText($encoded, 74, true);
return $encoded;
}
/**
* Encode string to q encoding.
* @access private
* @return string
*/
function EncodeQ ($str, $position = "text") {
// There should not be any EOL in the string
$encoded = preg_replace("[\r\n]", "", $str);
switch (strtolower($position)) {
case "phrase":
$encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
break;
case "comment":
$encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
case "text":
default:
// Replace every high ascii, control =, ? and _ characters
$encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
"'='.sprintf('%02X', ord('\\1'))", $encoded);
break;
}
// Replace every spaces to _ (more readable than =20)
$encoded = str_replace(" ", "_", $encoded);
return $encoded;
}
/**
* Adds a string or binary attachment (non-filesystem) to the list.
* This method can be used to attach ascii or binary data,
* such as a BLOB record from a database.
* @param string $string String attachment data.
* @param string $filename Name of the attachment.
* @param string $encoding File encoding (see $Encoding).
* @param string $type File extension (MIME) type.
* @return void
*/
function AddStringAttachment($string, $filename, $encoding = "base64",
$type = "application/octet-stream") {
// Append to $attachment array
$cur = count($this->attachment);
$this->attachment[$cur][0] = $string;
$this->attachment[$cur][1] = $filename;
$this->attachment[$cur][2] = $filename;
$this->attachment[$cur][3] = $encoding;
$this->attachment[$cur][4] = $type;
$this->attachment[$cur][5] = true; // isString
$this->attachment[$cur][6] = "attachment";
$this->attachment[$cur][7] = 0;
}
/**
* Adds an embedded attachment. This can include images, sounds, and
* just about any other document. Make sure to set the $type to an
* image type. For JPEG images use "image/jpeg" and for GIF images
* use "image/gif".
* @param string $path Path to the attachment.
* @param string $cid Content ID of the attachment. Use this to identify
* the Id for accessing the image in an HTML form.
* @param string $name Overrides the attachment name.
* @param string $encoding File encoding (see $Encoding).
* @param string $type File extension (MIME) type.
* @return bool
*/
function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64",
$type = "application/octet-stream") {
if(!@is_file($path))
{
$this->SetError($this->Lang("file_access") . $path);
return false;
}
$filename = basename($path);
if($name == "")
$name = $filename;
// Append to $attachment array
$cur = count($this->attachment);
$this->attachment[$cur][0] = $path;
$this->attachment[$cur][1] = $filename;
$this->attachment[$cur][2] = $name;
$this->attachment[$cur][3] = $encoding;
$this->attachment[$cur][4] = $type;
$this->attachment[$cur][5] = false; // isStringAttachment
$this->attachment[$cur][6] = "inline";
$this->attachment[$cur][7] = $cid;
return true;
}
/**
* Returns true if an inline attachment is present.
* @access private
* @return bool
*/
function InlineImageExists() {
$result = false;
for($i = 0; $i < count($this->attachment); $i++)
{
if($this->attachment[$i][6] == "inline")
{
$result = true;
break;
}
}
return $result;
}
/////////////////////////////////////////////////
// MESSAGE RESET METHODS
/////////////////////////////////////////////////
/**
* Clears all recipients assigned in the TO array. Returns void.
* @return void
*/
function ClearAddresses() {
$this->to = array();
}
/**
* Clears all recipients assigned in the CC array. Returns void.
* @return void
*/
function ClearCCs() {
$this->cc = array();
}
/**
* Clears all recipients assigned in the BCC array. Returns void.
* @return void
*/
function ClearBCCs() {
$this->bcc = array();
}
/**
* Clears all recipients assigned in the ReplyTo array. Returns void.
* @return void
*/
function ClearReplyTos() {
$this->ReplyTo = array();
}
/**
* Clears all recipients assigned in the TO, CC and BCC
* array. Returns void.
* @return void
*/
function ClearAllRecipients() {
$this->to = array();
$this->cc = array();
$this->bcc = array();
}
/**
* Clears all previously set filesystem, string, and binary
* attachments. Returns void.
* @return void
*/
function ClearAttachments() {
$this->attachment = array();
}
/**
* Clears all custom headers. Returns void.
* @return void
*/
function ClearCustomHeaders() {
$this->CustomHeader = array();
}
/////////////////////////////////////////////////
// MISCELLANEOUS METHODS
/////////////////////////////////////////////////
/**
* Adds the error message to the error container.
* Returns void.
* @access private
* @return void
*/
function SetError($msg) {
$this->error_count++;
$this->ErrorInfo = $msg;
}
/**
* Returns the proper RFC 822 formatted date.
* @access private
* @return string
*/
function RFCDate() {
$tz = date("Z");
$tzs = ($tz < 0) ? "-" : "+";
$tz = abs($tz);
$tz = ($tz/3600)*100 + ($tz%3600)/60;
$result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz);
return $result;
}
/**
* Returns the appropriate server variable. Should work with both
* PHP 4.1.0+ as well as older versions. Returns an empty string
* if nothing is found.
* @access private
* @return mixed
*/
function ServerVar($varName) {
global $HTTP_SERVER_VARS;
global $HTTP_ENV_VARS;
if(!isset($_SERVER))
{
$_SERVER = $HTTP_SERVER_VARS;
if(!isset($_SERVER["REMOTE_ADDR"]))
$_SERVER = $HTTP_ENV_VARS; // must be Apache
}
if(isset($_SERVER[$varName]))
return $_SERVER[$varName];
else
return "";
}
/**
* Returns the server hostname or 'localhost.localdomain' if unknown.
* @access private
* @return string
*/
function ServerHostname() {
if ($this->Hostname != "")
$result = $this->Hostname;
elseif ($this->ServerVar('SERVER_NAME') != "")
$result = $this->ServerVar('SERVER_NAME');
else
$result = "localhost.localdomain";
return $result;
}
/**
* Returns a message in the appropriate language.
* @access private
* @return string
*/
function Lang($key) {
if(count($this->language) < 1)
$this->SetLanguage("en"); // set the default language
if(isset($this->language[$key]))
return $this->language[$key];
else
return "Language string failed to load: " . $key;
}
/**
* Returns true if an error occurred.
* @return bool
*/
function IsError() {
return ($this->error_count > 0);
}
/**
* Changes every end of line from CR or LF to CRLF.
* @access private
* @return string
*/
function FixEOL($str) {
$str = str_replace("\r\n", "\n", $str);
$str = str_replace("\r", "\n", $str);
$str = str_replace("\n", $this->LE, $str);
return $str;
}
/**
* Adds a custom header.
* @return void
*/
function AddCustomHeader($custom_header) {
$this->CustomHeader[] = explode(":", $custom_header, 2);
}
}
?>
<?php
////////////////////////////////////////////////////
// SMTP - PHP SMTP class
//
// Version 1.02
//
// Define an SMTP class that can be used to connect
// and communicate with any SMTP server. It implements
// all the SMTP functions defined in RFC821 except TURN.
//
// Author: Chris Ryan
//
// License: LGPL, see LICENSE
////////////////////////////////////////////////////
/**
* SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
* commands except TURN which will always return a not implemented
* error. SMTP also provides some utility methods for sending mail
* to an SMTP server.
* @package PHPMailer
* @author Chris Ryan
*/
class SMTP
{
/**
* SMTP server port
* @var int
*/
var $SMTP_PORT = 25;
/**
* SMTP reply line ending
* @var string
*/
var $CRLF = "\r\n";
/**
* Sets whether debugging is turned on
* @var bool
*/
var $do_debug; # the level of debug to perform
/**#@+
* @access private
*/
var $smtp_conn; # the socket to the server
var $error; # error if any on the last call
var $helo_rply; # the reply the server sent to us for HELO
/**#@-*/
/**
* Initialize the class so that the data is in a known state.
* @access public
* @return void
*/
function SMTP() {
$this->smtp_conn = 0;
$this->error = null;
$this->helo_rply = null;
$this->do_debug = 0;
}
/*************************************************************
* CONNECTION FUNCTIONS *
***********************************************************/
/**
* Connect to the server specified on the port specified.
* If the port is not specified use the default SMTP_PORT.
* If tval is specified then a connection will try and be
* established with the server for that number of seconds.
* If tval is not specified the default is 30 seconds to
* try on the connection.
*
* SMTP CODE SUCCESS: 220
* SMTP CODE FAILURE: 421
* @access public
* @return bool
*/
function Connect($host,$port=0,$tval=30) {
# set the error val to null so there is no confusion
$this->error = null;
# make sure we are __not__ connected
if($this->connected()) {
# ok we are connected! what should we do?
# for now we will just give an error saying we
# are already connected
$this->error =
array("error" => "Already connected to a server");
return false;
}
if(empty($port)) {
$port = $this->SMTP_PORT;
}
#connect to the smtp server
if(!@ $this->smtp_conn = fsockopen($host, # the host of the server
$port, # the port to use
$errno, # error number if any
$errstr, # error message if any
$tval)) # give up after ? secs
{
// echo '<b><center>Could Not connect to Mail Server</b><br><br>';
return false;
}
# verify we connected properly
if(empty($this->smtp_conn)) {
$this->error = array("error" => "Failed to connect to server",
"errno" => $errno,
"errstr" => $errstr);
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": $errstr ($errno)" . $this->CRLF;
}
return false;
}
# sometimes the SMTP server takes a little longer to respond
# so we will give it a longer timeout for the first read
// Windows still does not have support for this timeout function
if(substr(PHP_OS, 0, 3) != "WIN")
socket_set_timeout($this->smtp_conn, $tval, 0);
# get any announcement stuff
$announce = $this->get_lines();
# set the timeout of any socket functions at 1/10 of a second
//if(function_exists("socket_set_timeout"))
// socket_set_timeout($this->smtp_conn, 0, 100000);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
}
return true;
}
/**
* Performs SMTP authentication. Must be run after running the
* Hello() method. Returns true if successfully authenticated.
* @access public
* @return bool
*/
function Authenticate($username, $password) {
// Start authentication
fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($code != 334) {
$this->error =
array("error" => "AUTH not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
// Send encoded username
fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($code != 334) {
$this->error =
array("error" => "Username not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
// Send encoded password
fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($code != 235) {
$this->error =
array("error" => "Password not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Returns true if connected to a server otherwise false
* @access private
* @return bool
*/
function Connected() {
if(!empty($this->smtp_conn)) {
$sock_status = socket_get_status($this->smtp_conn);
if($sock_status["eof"]) {
# hmm this is an odd situation... the socket is
# valid but we aren't connected anymore
if($this->do_debug >= 1) {
echo "SMTP -> NOTICE:" . $this->CRLF .
"EOF caught while checking if connected";
}
$this->Close();
return false;
}
return true; # everything looks good
}
return false;
}
/**
* Closes the socket and cleans up the state of the class.
* It is not considered good to use this function without
* first trying to use QUIT.
* @access public
* @return void
*/
function Close() {
$this->error = null; # so there is no confusion
$this->helo_rply = null;
if(!empty($this->smtp_conn)) {
# close the connection and cleanup
fclose($this->smtp_conn);
$this->smtp_conn = 0;
}
}
/***************************************************************
* SMTP COMMANDS *
*************************************************************/
/**
* Issues a data command and sends the msg_data to the server
* finializing the mail transaction. $msg_data is the message
* that is to be send with the headers. Each header needs to be
* on a single line followed by a <CRLF> with the message headers
* and the message body being seperated by and additional <CRLF>.
*
* Implements rfc 821: DATA <CRLF>
*
* SMTP CODE INTERMEDIATE: 354
* [data]
* <CRLF>.<CRLF>
* SMTP CODE SUCCESS: 250
* SMTP CODE FAILURE: 552,554,451,452
* SMTP CODE FAILURE: 451,554
* SMTP CODE ERROR : 500,501,503,421
* @access public
* @return bool
*/
function Data($msg_data) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Data() without being connected");
return false;
}
fputs($this->smtp_conn,"DATA" . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 354) {
$this->error =
array("error" => "DATA command not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
# the server is ready to accept data!
# according to rfc 821 we should not send more than 1000
# including the CRLF
# characters on a single line so we will break the data up
# into lines by \r and/or \n then if needed we will break
# each of those into smaller lines to fit within the limit.
# in addition we will be looking for lines that start with
# a period '.' and append and additional period '.' to that
# line. NOTE: this does not count towards are limit.
# normalize the line breaks so we know the explode works
$msg_data = str_replace("\r\n","\n",$msg_data);
$msg_data = str_replace("\r","\n",$msg_data);
$lines = explode("\n",$msg_data);
# we need to find a good way to determine is headers are
# in the msg_data or if it is a straight msg body
# currently I'm assuming rfc 822 definitions of msg headers
# and if the first field of the first line (':' sperated)
# does not contain a space then it _should_ be a header
# and we can process all lines before a blank "" line as
# headers.
$field = substr($lines[0],0,strpos($lines[0],":"));
$in_headers = false;
if(!empty($field) && !strstr($field," ")) {
$in_headers = true;
}
$max_line_length = 998; # used below; set here for ease in change
while(list(,$line) = @each($lines)) {
$lines_out = null;
if($line == "" && $in_headers) {
$in_headers = false;
}
# ok we need to break this line up into several
# smaller lines
while(strlen($line) > $max_line_length) {
$pos = strrpos(substr($line,0,$max_line_length)," ");
$lines_out[] = substr($line,0,$pos);
$line = substr($line,$pos + 1);
# if we are processing headers we need to
# add a LWSP-char to the front of the new line
# rfc 822 on long msg headers
if($in_headers) {
$line = "\t" . $line;
}
}
$lines_out[] = $line;
# now send the lines to the server
while(list(,$line_out) = @each($lines_out)) {
if(strlen($line_out) > 0)
{
if(substr($line_out, 0, 1) == ".") {
$line_out = "." . $line_out;
}
}
fputs($this->smtp_conn,$line_out . $this->CRLF);
}
}
# ok all the message data has been sent so lets get this
# over with aleady
fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "DATA not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Expand takes the name and asks the server to list all the
* people who are members of the _list_. Expand will return
* back and array of the result or false if an error occurs.
* Each value in the array returned has the format of:
* [ <full-name> <sp> ] <path>
* The definition of <path> is defined in rfc 821
*
* Implements rfc 821: EXPN <SP> <string> <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE FAILURE: 550
* SMTP CODE ERROR : 500,501,502,504,421
* @access public
* @return string array
*/
function Expand($name) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Expand() without being connected");
return false;
}
fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "EXPN not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
# parse the reply and place in our array to return to user
$entries = explode($this->CRLF,$rply);
while(list(,$l) = @each($entries)) {
$list[] = substr($l,4);
}
return $list;
}
/**
* Sends the HELO command to the smtp server.
* This makes sure that we and the server are in
* the same known state.
*
* Implements from rfc 821: HELO <SP> <domain> <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE ERROR : 500, 501, 504, 421
* @access public
* @return bool
*/
function Hello($host="") {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Hello() without being connected");
return false;
}
# if a hostname for the HELO wasn't specified determine
# a suitable one to send
if(empty($host)) {
# we need to determine some sort of appopiate default
# to send to the server
$host = "localhost";
}
// Send extended hello first (RFC 2821)
if(!$this->SendHello("EHLO", $host))
{
if(!$this->SendHello("HELO", $host))
return false;
}
return true;
}
/**
* Sends a HELO/EHLO command.
* @access private
* @return bool
*/
function SendHello($hello, $host) {
fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => $hello . " not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
$this->helo_rply = $rply;
return true;
}
/**
* Gets help information on the keyword specified. If the keyword
* is not specified then returns generic help, ussually contianing
* A list of keywords that help is available on. This function
* returns the results back to the user. It is up to the user to
* handle the returned data. If an error occurs then false is
* returned with $this->error set appropiately.
*
* Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
*
* SMTP CODE SUCCESS: 211,214
* SMTP CODE ERROR : 500,501,502,504,421
* @access public
* @return string
*/
function Help($keyword="") {
$this->error = null; # to avoid confusion
if(!$this->connected()) {
$this->error = array(
"error" => "Called Help() without being connected");
return false;
}
$extra = "";
if(!empty($keyword)) {
$extra = " " . $keyword;
}
fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 211 && $code != 214) {
$this->error =
array("error" => "HELP not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return $rply;
}
/**
* Starts a mail transaction from the email address specified in
* $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more Recipient
* commands may be called followed by a Data command.
*
* Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE SUCCESS: 552,451,452
* SMTP CODE SUCCESS: 500,501,421
* @access public
* @return bool
*/
function Mail($from) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Mail() without being connected");
return false;
}
fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "MAIL not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Sends the command NOOP to the SMTP server.
*
* Implements from rfc 821: NOOP <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE ERROR : 500, 421
* @access public
* @return bool
*/
function Noop() {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Noop() without being connected");
return false;
}
fputs($this->smtp_conn,"NOOP" . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "NOOP not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Sends the quit command to the server and then closes the socket
* if there is no error or the $close_on_error argument is true.
*
* Implements from rfc 821: QUIT <CRLF>
*
* SMTP CODE SUCCESS: 221
* SMTP CODE ERROR : 500
* @access public
* @return bool
*/
function Quit($close_on_error=true) {
$this->error = null; # so there is no confusion
if(!$this->connected()) {
$this->error = array(
"error" => "Called Quit() without being connected");
return false;
}
# send the quit command to the server
fputs($this->smtp_conn,"quit" . $this->CRLF);
# get any good-bye messages
$byemsg = $this->get_lines();
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
}
$rval = true;
$e = null;
$code = substr($byemsg,0,3);
if($code != 221) {
# use e as a tmp var cause Close will overwrite $this->error
$e = array("error" => "SMTP server rejected quit command",
"smtp_code" => $code,
"smtp_rply" => substr($byemsg,4));
$rval = false;
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $e["error"] . ": " .
$byemsg . $this->CRLF;
}
}
if(empty($e) || $close_on_error) {
$this->Close();
}
return $rval;
}
/**
* Sends the command RCPT to the SMTP server with the TO: argument of $to.
* Returns true if the recipient was accepted false if it was rejected.
*
* Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
*
* SMTP CODE SUCCESS: 250,251
* SMTP CODE FAILURE: 550,551,552,553,450,451,452
* SMTP CODE ERROR : 500,501,503,421
* @access public
* @return bool
*/
function Recipient($to) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Recipient() without being connected");
return false;
}
fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250 && $code != 251) {
$this->error =
array("error" => "RCPT not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Sends the RSET command to abort and transaction that is
* currently in progress. Returns true if successful false
* otherwise.
*
* Implements rfc 821: RSET <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE ERROR : 500,501,504,421
* @access public
* @return bool
*/
function Reset() {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Reset() without being connected");
return false;
}
fputs($this->smtp_conn,"RSET" . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "RSET failed",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Starts a mail transaction from the email address specified in
* $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more Recipient
* commands may be called followed by a Data command. This command
* will send the message to the users terminal if they are logged
* in.
*
* Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE SUCCESS: 552,451,452
* SMTP CODE SUCCESS: 500,501,502,421
* @access public
* @return bool
*/
function Send($from) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Send() without being connected");
return false;
}
fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "SEND not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Starts a mail transaction from the email address specified in
* $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more Recipient
* commands may be called followed by a Data command. This command
* will send the message to the users terminal if they are logged
* in and send them an email.
*
* Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE SUCCESS: 552,451,452
* SMTP CODE SUCCESS: 500,501,502,421
* @access public
* @return bool
*/
function SendAndMail($from) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called SendAndMail() without being connected");
return false;
}
fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "SAML not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* Starts a mail transaction from the email address specified in
* $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more Recipient
* commands may be called followed by a Data command. This command
* will send the message to the users terminal if they are logged
* in or mail it to them if they are not.
*
* Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE SUCCESS: 552,451,452
* SMTP CODE SUCCESS: 500,501,502,421
* @access public
* @return bool
*/
function SendOrMail($from) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called SendOrMail() without being connected");
return false;
}
fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250) {
$this->error =
array("error" => "SOML not accepted from server",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return true;
}
/**
* This is an optional command for SMTP that this class does not
* support. This method is here to make the RFC821 Definition
* complete for this class and __may__ be implimented in the future
*
* Implements from rfc 821: TURN <CRLF>
*
* SMTP CODE SUCCESS: 250
* SMTP CODE FAILURE: 502
* SMTP CODE ERROR : 500, 503
* @access public
* @return bool
*/
function Turn() {
$this->error = array("error" => "This method, TURN, of the SMTP ".
"is not implemented");
if($this->do_debug >= 1) {
echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
}
return false;
}
/**
* Verifies that the name is recognized by the server.
* Returns false if the name could not be verified otherwise
* the response from the server is returned.
*
* Implements rfc 821: VRFY <SP> <string> <CRLF>
*
* SMTP CODE SUCCESS: 250,251
* SMTP CODE FAILURE: 550,551,553
* SMTP CODE ERROR : 500,501,502,421
* @access public
* @return int
*/
function Verify($name) {
$this->error = null; # so no confusion is caused
if(!$this->connected()) {
$this->error = array(
"error" => "Called Verify() without being connected");
return false;
}
fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
}
if($code != 250 && $code != 251) {
$this->error =
array("error" => "VRFY failed on name '$name'",
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
echo "SMTP -> ERROR: " . $this->error["error"] .
": " . $rply . $this->CRLF;
}
return false;
}
return $rply;
}
/*******************************************************************
* INTERNAL FUNCTIONS *
******************************************************************/
/**
* Read in as many lines as possible
* either before eof or socket timeout occurs on the operation.
* With SMTP we can tell if we have more lines to read if the
* 4th character is '-' symbol. If it is a space then we don't
* need to read anything else.
* @access private
* @return string
*/
function get_lines() {
$data = "";
while($str = fgets($this->smtp_conn,515)) {
if($this->do_debug >= 4) {
echo "SMTP -> get_lines(): \$data was \"$data\"" .
$this->CRLF;
echo "SMTP -> get_lines(): \$str is \"$str\"" .
$this->CRLF;
}
$data .= $str;
if($this->do_debug >= 4) {
echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
}
# if the 4th character is a space then we are done reading
# so just break the loop
if(substr($str,3,1) == " ") { break; }
}
return $data;
}
}
?>
......@@ -22,7 +22,7 @@ $mailserveresult = $adb->pquery("SELECT server,server_username,server_password,s
$mailrow = $adb->fetch_array($mailserveresult);
$mailserver = $mailrow[0];
$mailuname = $mailrow[1];
$mailpwd = $mailrow[2];
$mailpwd = Vtiger_Functions::fromProtectedText($mailrow[2]);
$smtp_auth = $mailrow[3];
// End Email Setup
......@@ -39,7 +39,7 @@ if($activevalue[0] == 1)
//get all those activities where the status is not completed even after the passing of 24 hours
$today = date("Ymd");
$result = $adb->pquery("select vtiger_activity.status,vtiger_activity.activityid,subject,(vtiger_activity.date_start +1),vtiger_crmentity.smownerid from vtiger_activity inner join vtiger_crmentity on vtiger_crmentity.crmid=vtiger_activity.activityid where vtiger_crmentity.deleted=0 and vtiger_activity.status <> 'Completed' and activitytype='Task' and ".$today." > (vtiger_activity.date_start+1)", array());
$result = $adb->pquery("select vtiger_activity.status,vtiger_activity.activityid,subject,(vtiger_activity.date_start +1),vtiger_crmentity.smownerid from vtiger_activity inner join vtiger_crmentity on vtiger_crmentity.crmid=vtiger_activity.activityid where vtiger_crmentity.deleted=0 and vtiger_activity.status <> 'Completed' and activitytype='Task' and ? > (vtiger_activity.date_start+1)", array($today));
while ($myrow = $adb->fetch_array($result))
{
......
<?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.
********************************************************************************/
$mysql_dir = 'MYSQLINSTALLDIR';
$mysql_username = 'MYSQLUSERNAME';
$mysql_password = 'MYSQLPASSWORD';
$mysql_port = 'MYSQLPORT';
$mysql_bundled = 'MYSQLBUNDLEDSTATUS';
$apache_dir = 'APACHEINSTALLDIR';
$apache_bin = 'APACHEBIN';
$apache_conf = 'APACHECONF';
$apache_port = 'APACHEPORT';
$apache_bundled = 'APACHEBUNDLED';
?>
*************************************************************************************/
require_once 'modules/Oauth2/handlers/TokenRefresher.php';
$tokenRefresher = new Oauth2_TokenRefresher_Handler();
$tokenRefresher->refreshAll();
\ No newline at end of file
......@@ -12,7 +12,7 @@ require_once('include/utils/utils.php');
require_once('include/logging.php');
global $adb, $log;
$log =& LoggerManager::getLogger('RecurringInvoice');
$log = Logger::getLogger('RecurringInvoice');
$log->debug("invoked RecurringInvoice");
$currentDate = date('Y-m-d');
......@@ -22,8 +22,8 @@ $sql="SELECT vtiger_salesorder.salesorderid, recurring_frequency, start_period,
payment_duration, invoice_status FROM vtiger_salesorder
INNER JOIN vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid AND vtiger_crmentity.deleted = 0
INNER JOIN vtiger_invoice_recurring_info ON vtiger_salesorder.salesorderid = vtiger_invoice_recurring_info.salesorderid
WHERE DATE_FORMAT(start_period,'%Y-%m-%d') <= '$currentDate' AND DATE_FORMAT(end_period,'%Y-%m-%d') >= '$currentDate'";
$result = $adb->pquery($sql, array());
WHERE DATE_FORMAT(start_period,'%Y-%m-%d') <= ? AND DATE_FORMAT(end_period,'%Y-%m-%d') >= ?";
$result = $adb->pquery($sql, array($currentDate, $currentDate));
$no_of_salesorder = $adb->num_rows($result);
for($i=0; $i<$no_of_salesorder;$i++) {
......@@ -159,6 +159,7 @@ function getRecurringDate($recurringDate, $recurringFrequency) {
case 'monthly' : $m = $m + 1; break;
case 'quarterly' : $m = $m + 3; break;
case 'every 4 months': $m = $m + 4; break;
case 'half-yearly' : $m = $m + 6; break;
case 'yearly' : $y = $y + 1; break;
......@@ -185,4 +186,3 @@ function getRecurringDate($recurringDate, $recurringFrequency) {
return array('validDate' => $validNextRecurringDate, 'nextRecurringDate' => $nextRecurringDate);
}
?>
......@@ -22,13 +22,13 @@
//file modified by richie
require("class.smtp.php");
require("class.phpmailer.php");
// require_once("modules/Emails/class.smtp.php");
// require_once("modules/Emails/class.phpmailer.php");
require_once 'include/utils/CommonUtils.php';
function sendmail($to,$from,$subject,$contents,$mail_server,$mail_server_username,$mail_server_password,$filename,$smtp_auth='')
{
$mail = new PHPMailer();
$mail = new PHPMailer\PHPMailer\PHPMailer();
$mail->Subject = $subject;
$mail->Body = $contents;//"This is the HTML message body <b>in bold!</b>";
......@@ -42,17 +42,17 @@ function sendmail($to,$from,$subject,$contents,$mail_server,$mail_server_usernam
else
$mail->SMTPAuth = false;
$mail->Username = $mail_server_username ;//$smtp_username; // SMTP username
$mail->Password = $mail_server_password ;//$smtp_password; // SMTP password
$mail->Password = Vtiger_Functions::fromProtectedText($mail_server_password);//$smtp_password; // SMTP password
$mail->From = $from;
$mail->FromName = $initialfrom;
$mail->AddAddress($to); // name is optional
$mail->AddReplyTo($from);
$mail->WordWrap = 50; // set word wrap to 50 characters
$mail->IsHTML(true); // set email format to HTML
$mail->AltBody = "This is the body in plain text for non-HTML mail clients";
// $mail->Sender= getReturnPath($mail->Host);
if(!$mail->Send())
if(!$mail->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail->ErrorInfo;
......
......@@ -28,11 +28,14 @@ require_once('include/utils/UserInfoUtil.php');
require_once("include/Zend/Json.php");
require_once 'include/RelatedListView.php';
#[\AllowDynamicProperties]
class CRMEntity {
var $ownedby;
var $recordSource = 'CRM';
var $mode;
public $moduleName;
/**
* Detect if we are in bulk save mode, where some features can be turned-off
* to improve performance.
......@@ -112,7 +115,7 @@ class CRMEntity {
}
// added to support files transformation for file upload fields like uitype 69,
if(count($_FILES)) {
if(!empty($_FILES) && php7_count($_FILES)) {
$_FILES = Vtiger_Util_Helper::transformUploadedFiles($_FILES, true);
}
......@@ -131,7 +134,8 @@ class CRMEntity {
$this->db->completeTransaction();
// vtlib customization: Hook provide to enable generic module relation.
if ($_REQUEST['createmode'] == 'link' && !$_REQUEST['__linkcreated']) {
if ( (isset($_REQUEST['createmode']) && $_REQUEST['createmode'] == 'link') &&
!isset($_REQUEST['__linkcreated'])) {
$_REQUEST['__linkcreated'] = true;
$for_module = vtlib_purify($_REQUEST['return_module']);
$for_crmid = vtlib_purify($_REQUEST['return_id']);
......@@ -156,7 +160,7 @@ class CRMEntity {
*/
function uploadAndSaveFile($id, $module, $file_details, $attachmentType='Attachment') {
global $log;
$log->debug("Entering into uploadAndSaveFile($id,$module,$file_details) method.");
$log->debug("Entering into uploadAndSaveFile($id,$module) method.");
global $adb, $current_user;
global $upload_badext;
......@@ -175,7 +179,7 @@ class CRMEntity {
}
// Check 1
$save_file = 'true';
$save_file = true;
//only images are allowed for Image Attachmenttype
$mimeType = vtlib_mime_content_type($file_details['tmp_name']);
$mimeTypeContents = explode('/', $mimeType);
......@@ -183,17 +187,18 @@ class CRMEntity {
if ($attachmentType == 'Image' || ($file_details['size'] && $mimeTypeContents[0] == 'image')) {
$save_file = validateImageFile($file_details);
}
if ($save_file == 'false') {
$log->debug("File Validation status in Check1 save_file => $save_file");
if (!$save_file) {
return false;
}
// Check 2
$save_file = 'true';
$save_file = true;
//only images are allowed for these modules
if ($module == 'Contacts' || $module == 'Products') {
$save_file = validateImageFile($file_details);
}
$log->debug("File Validation status in Check2 save_file => $save_file");
$binFile = sanitizeUploadFileName($file_name, $upload_badext);
$current_id = $adb->getUniqueID("vtiger_crmentity");
......@@ -206,10 +211,11 @@ class CRMEntity {
$upload_file_path = decideFilePath();
// upload the file in server
$upload_status = copy($filetmp_name, $upload_file_path . $current_id . "_" . $binFile);
$encryptFileName = Vtiger_Util_Helper::getEncryptedFileName($binFile);
$upload_status = copy($filetmp_name, $upload_file_path . $current_id . "_" . $encryptFileName);
// temporary file will be deleted at the end of request
if ($save_file == 'true' && $upload_status == 'true') {
$log->debug("Upload status of file => $upload_status");
if ($save_file && $upload_status == 'true') {
if($attachmentType != 'Image' && $this->mode == 'edit') {
//Only one Attachment per entity delete previous attachments
$res = $adb->pquery('SELECT vtiger_seattachmentsrel.attachmentsid FROM vtiger_seattachmentsrel
......@@ -219,7 +225,7 @@ class CRMEntity {
for($attachItr = 0;$attachItr < $adb->num_rows($res);$attachItr++) {
$oldAttachmentIds[] = $adb->query_result($res,$attachItr,'attachmentsid');
}
if(count($oldAttachmentIds)) {
if(php7_count($oldAttachmentIds)) {
$adb->pquery('DELETE FROM vtiger_seattachmentsrel WHERE attachmentsid IN ('.generateQuestionMarks($oldAttachmentIds).')',$oldAttachmentIds);
//TODO : revisit to delete actual file and attachment entry,as we need to see the deleted file in the history when its changed
//$adb->pquery('DELETE FROM vtiger_attachments WHERE attachmentsid IN ('.generateQuestionMarks($oldAttachmentIds).')',$oldAttachmentIds);
......@@ -231,16 +237,18 @@ class CRMEntity {
$params1 = array($current_id, $current_user->id, $ownerid, $module." ".$attachmentType, $this->column_fields['description'], $adb->formatDate($date_var, true), $adb->formatDate($date_var, true));
$adb->pquery($sql1, $params1);
//Add entry to attachments
$sql2 = "INSERT INTO vtiger_attachments(attachmentsid, name, description, type, path) values(?, ?, ?, ?, ?)";
$params2 = array($current_id, $filename, $this->column_fields['description'], $filetype, $upload_file_path);
$sql2 = "INSERT INTO vtiger_attachments(attachmentsid, name, description, type, path, storedname) values(?, ?, ?, ?, ?, ?)";
$params2 = array($current_id, $filename, $this->column_fields['description'], $filetype, $upload_file_path, $encryptFileName);
$adb->pquery($sql2, $params2);
//Add relation
$sql3 = 'INSERT INTO vtiger_seattachmentsrel VALUES(?,?)';
$params3 = array($id, $current_id);
$adb->pquery($sql3, $params3);
$log->debug("File uploaded successfully with id => $current_id");
return $current_id;
} else {
//failed to upload file
$log->debug('File upload failed');
return false;
}
}
......@@ -262,6 +270,7 @@ class CRMEntity {
$ownerid = $this->column_fields['assigned_user_id'];
$groupid = $this->column_fields['group_id'];
$insertion_mode = $this->mode;
if (empty($groupid))
$groupid = 0;
......@@ -274,6 +283,23 @@ class CRMEntity {
if ($module == 'Events') {
$module = 'Calendar';
}
$entityFields = Vtiger_Functions::getEntityModuleInfo($module);
$entityFieldNames = explode(',', $entityFields['fieldname']);
switch ($module) {
case 'HelpDesk': $entityFieldNames = array('ticket_title');
break;
case 'Documents': $entityFieldNames = array('notes_title');
break;
}
$record_label = '';
foreach($entityFieldNames as $entityFieldName) {
$record_label .= $this->column_fields[$entityFieldName]." ";
}
$label = decode_html($record_label);
$this->column_fields['label'] = $label;
if ($this->mode == 'edit') {
$description_val = from_html($this->column_fields['description'], ($insertion_mode == 'edit') ? true : false);
......@@ -287,8 +313,8 @@ class CRMEntity {
$acl = Vtiger_AccessControl::loadUserPrivileges($current_user->id);
if ($acl->is_admin == true || $acl->profileGlobalPermission[1] == 0 || $acl->profileGlobalPermission[2] == 0 || $this->isWorkFlowFieldUpdate) {
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?,description=?, modifiedtime=? where crmid=?";
$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true), $this->id);
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?,description=?, modifiedtime=?";
$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true));
} else {
$profileList = getCurrentUserProfileList();
$perm_qry = "SELECT columnname 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.readonly = 0 AND vtiger_profile2field.profileid IN (" . generateQuestionMarks($profileList) . ") AND vtiger_def_org_field.visible = 0 and vtiger_field.tablename='vtiger_crmentity' and vtiger_field.displaytype in (1,3) and vtiger_field.presence in (0,2);";
......@@ -298,13 +324,22 @@ class CRMEntity {
$columname[] = $adb->query_result($perm_result, $i, "columnname");
}
if (is_array($columname) && in_array("description", $columname)) {
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?, modifiedby=?,description=?, modifiedtime=? where crmid=?";
$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true), $this->id);
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?, modifiedby=?,description=?, modifiedtime=?";
$params = array($ownerid, $groupid, $current_user->id, $description_val, $adb->formatDate($date_var, true));
} else {
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?, modifiedtime=? where crmid=?";
$params = array($ownerid, $groupid, $current_user->id, $adb->formatDate($date_var, true), $this->id);
$sql = "update vtiger_crmentity set smownerid=?, smgroupid=?,modifiedby=?, modifiedtime=?";
$params = array($ownerid, $groupid, $current_user->id, $adb->formatDate($date_var, true));
}
}
if($label) {
$sql .= ", label = ? ";
array_push($params, trim($label));
}
$sql .= " where crmid=?";
array_push($params,$this->id);
$adb->pquery($sql, $params);
$this->column_fields['modifiedtime'] = $modified_date_var;
$this->column_fields['modifiedby'] = $current_user->id;
......@@ -334,9 +369,20 @@ class CRMEntity {
$source = strtoupper($this->recordSource);
}
$description_val = from_html($this->column_fields['description'], ($insertion_mode == 'edit') ? true : false);
$sql = "insert into vtiger_crmentity (crmid,smcreatorid,smownerid,smgroupid,setype,description,modifiedby,createdtime,modifiedtime,source) values(?,?,?,?,?,?,?,?,?,?)";
$params = array($current_id, $current_user->id, $ownerid, $groupid, $module, $description_val, $current_user->id, $created_date_var, $modified_date_var,$source);
$description_val = from_html($this->column_fields['description'], ($this->mode == 'edit') ? true : false);
$params = array("crmid" => $current_id, "smcreatorid" => $current_user->id, "smownerid" => $ownerid,
"smgroupid" => $groupid, "setype" => $module, "description" => $description_val,
"modifiedby" => $current_user->id, "createdtime" => $created_date_var,
"modifiedtime" => $modified_date_var, "source" => $source);
if($label) {
$params['label'] = trim($label);
}
$insert_columns = array_keys($params);
$insert_data = array_values($params);
$sql = "insert into vtiger_crmentity (".implode(",",$insert_columns).") values(".generateQuestionMarks($insert_data).")";
$adb->pquery($sql, $params);
$this->column_fields['createdtime'] = $created_date_var;
......@@ -365,11 +411,13 @@ class CRMEntity {
global $current_user, $app_strings;
$log->info("function insertIntoEntityTable " . $module . ' vtiger_table name ' . $table_name);
global $adb;
global $_FILES;
$insertion_mode = $this->mode;
$table_name = Vtiger_Util_Helper::validateStringForSql($table_name);
$tablekey = $this->tab_name_index[$table_name];
//Checkin whether an entry is already is present in the vtiger_table to update
if ($insertion_mode == 'edit') {
$tablekey = $this->tab_name_index[$table_name];
// Make selection on the primary key of the module table to check.
$check_query = "select $tablekey from $table_name where $tablekey=?";
$check_params = array($this->id);
......@@ -403,7 +451,7 @@ class CRMEntity {
} else {
$profileList = getCurrentUserProfileList();
if (count($profileList) > 0) {
if (php7_count($profileList) > 0) {
$sql = "SELECT vtiger_field.fieldname,vtiger_field.columnname,vtiger_field.uitype,vtiger_field.generatedtype,vtiger_field.typeofdata FROM vtiger_field
INNER JOIN vtiger_profile2field
ON vtiger_profile2field.fieldid = vtiger_field.fieldid
......@@ -463,7 +511,7 @@ class CRMEntity {
}
} else { // Useful when doing bulk save
$result = $_privatecache[$cachekey];
$noofrows = count($result);
$noofrows = php7_count($result);
}
for ($i = 0; $i < $noofrows; $i++) {
......@@ -478,9 +526,11 @@ class CRMEntity {
$datatype = $typeofdata_array[0];
$ajaxSave = false;
if (($_REQUEST['file'] == 'DetailViewAjax' && $_REQUEST['ajxaction'] == 'DETAILVIEW'
&& isset($_REQUEST["fldName"]) && $_REQUEST["fldName"] != $fieldname)
|| ($_REQUEST['action'] == 'MassEditSave' && !isset($_REQUEST[$fieldname."_mass_edit_check"]))) {
if ( (isset($_REQUEST['file']) && $_REQUEST['file'] == 'DetailViewAjax') &&
(isset($_REQUEST['ajaxaction']) && $_REQUEST['ajxaction'] == 'DETAILVIEW') &&
(isset($_REQUEST["fldName"]) && $_REQUEST["fldName"] != $fieldname) ||
((isset($_REQUEST['action']) && $_REQUEST['action'] == 'MassEditSave') &&
!isset($_REQUEST[$fieldname."_mass_edit_check"]))) {
$ajaxSave = true;
}
......@@ -520,11 +570,11 @@ class CRMEntity {
} elseif ($uitype == 5 || $uitype == 6 || $uitype == 23) {
//Added to avoid function call getDBInsertDateValue in ajax save
if (isset($current_user->date_format) && !$ajaxSave) {
$fldvalue = getValidDBInsertDateValue($this->column_fields[$fieldname]);
$fldvalue = getValidDBInsertDateTimeValue($this->column_fields[$fieldname]);
} else {
$fldvalue = $this->column_fields[$fieldname];
}
} elseif ($uitype == 7) {
} elseif ($uitype == 7 || $uitype == 9) {
//strip out the spaces and commas in numbers if given ie., in amounts there may be ,
$fldvalue = str_replace(",", "", $this->column_fields[$fieldname]); //trim($this->column_fields[$fieldname],",");
if (in_array($datatype, array('N', 'NN'))) {
......@@ -552,7 +602,7 @@ class CRMEntity {
$fldvalue = decode_html($this->column_fields[$fieldname]);
}
} elseif ($uitype == 8) {
$this->column_fields[$fieldname] = rtrim($this->column_fields[$fieldname], ',');
$this->column_fields[$fieldname] = isset($this->column_fields[$fieldname]) ? rtrim($this->column_fields[$fieldname], ',') : '';
$ids = explode(',', $this->column_fields[$fieldname]);
$json = new Zend_Json();
$fldvalue = $json->encode($ids);
......@@ -577,7 +627,7 @@ class CRMEntity {
$fldvalue = CurrencyField::convertToDBFormat($this->column_fields[$fieldname]);
} elseif ($uitype == 69) {
$fldvalue = $this->column_fields[$fieldname];
if(count($_FILES)) {
if(php7_count($_FILES)) {
$IMG_FILES = $_FILES[$fieldname];
if($_REQUEST['action'] == 'MassSave' || $_REQUEST['action'] == 'MassEditSave') {
if($IMG_FILES[0]['error'] == 0) {
......@@ -589,7 +639,7 @@ class CRMEntity {
for($itr = 0;$itr < $adb->num_rows($oldAttachmentsRes);$itr++) {
$oldImageAttachmentIds[] = $adb->query_result($oldAttachmentsRes,$itr,'attachmentsid');
}
if(count($oldImageAttachmentIds)) {
if(php7_count($oldImageAttachmentIds)) {
$adb->pquery('DELETE FROM vtiger_seattachmentsrel WHERE attachmentsid IN ('.generateQuestionMarks($oldImageAttachmentIds).')',$oldImageAttachmentIds);
$adb->pquery('DELETE FROM vtiger_attachments WHERE attachmentsid IN ('.generateQuestionMarks($oldImageAttachmentIds).')',$oldImageAttachmentIds);
$adb->pquery('DELETE FROM vtiger_crmentity WHERE crmid IN ('.generateQuestionMarks($oldImageAttachmentIds).')',$oldImageAttachmentIds);
......@@ -597,12 +647,12 @@ class CRMEntity {
}
}
$uploadedFileNames = array();
if(count($IMG_FILES)){
if(php7_count($IMG_FILES)){
foreach($IMG_FILES as $fileIndex => $file) {
if($file['error'] == 0 && $file['name'] != '' && $file['size'] > 0) {
if($_REQUEST[$fileIndex.'_hidden'] != '')
$file['original_name'] = vtlib_purify($_REQUEST[$fileindex.'_hidden']);
else {
if(isset($_REQUEST[$fileIndex.'_hidden']) && $_REQUEST[$fileIndex.'_hidden'] != '') {
$file['original_name'] = vtlib_purify($_REQUEST[$fileIndex.'_hidden']);
} else {
$file['original_name'] = stripslashes($file['name']);
}
$file['original_name'] = str_replace('"','',$file['original_name']);
......@@ -613,13 +663,13 @@ class CRMEntity {
}
}
}
if(count($uploadedFileNames)) {
if(php7_count($uploadedFileNames)) {
$fldvalue = implode(',',$uploadedFileNames);
} else {
$skipUpdateForField = true;
}
}
if (($insertion_mode == 'edit' && $skipUpdateForField == false) || $_REQUEST['imgDeleted']) {
if (($insertion_mode == 'edit' && $skipUpdateForField == false) || (isset($_REQUEST['imgDeleted']) && $_REQUEST['imgDeleted'])) {
$skipUpdateForField = false;
$uploadedFileNames = array();
$getImageNamesSql = 'SELECT name FROM vtiger_seattachmentsrel INNER JOIN vtiger_attachments ON
......@@ -633,13 +683,14 @@ class CRMEntity {
}
$fldvalue = implode(',',$uploadedFileNames);
}
}elseif ($uitype == 61 && count($_FILES)) {
}elseif ($uitype == 61 && php7_count($_FILES)) {
if($module == "ModComments") {
$UPLOADED_FILES = $_FILES[$fieldname];
$uploadedFileNames = array();
foreach($UPLOADED_FILES as $fileIndex => $file) {
if($file['error'] == 0 && $file['name'] != '' && $file['size'] > 0) {
if($_REQUEST[$fileindex.'_hidden'] != '') {
$file['original_name'] = vtlib_purify($_REQUEST[$fileindex.'_hidden']);
if(isset($_REQUEST[$fileIndex.'_hidden']) && $_REQUEST[$fileIndex.'_hidden'] != '') {
$file['original_name'] = vtlib_purify($_REQUEST[$fileIndex.'_hidden']);
} else {
$file['original_name'] = stripslashes($file['name']);
}
......@@ -650,7 +701,7 @@ class CRMEntity {
}
}
}
if(count($uploadedFileNames)) {
if(php7_count($uploadedFileNames)) {
$fldvalue = implode(',',$uploadedFileNames);
} else {
$skipUpdateForField = true;
......@@ -693,17 +744,21 @@ class CRMEntity {
//Track the update and update only when needed - vikas
$updateFieldValues = @array_combine($updateColumnNames, $update_params);
$changedFields = $this->column_fields->getChanged();
if(count($changedFields) > 0) {
if(php7_count($changedFields) > 0) {
$update = array();
$update_params = array();
foreach($changedFields as $field) {
if (!array_key_exists($field, $updateFieldNameColumnNameMap)) {
continue;
}
$fieldColumn = $updateFieldNameColumnNameMap[$field];
if(@array_key_exists($fieldColumn, $updateFieldValues)) {
if(array_key_exists($fieldColumn, $updateFieldValues)) {
array_push($update, $fieldColumn.'=?');
array_push($update_params, $updateFieldValues[$fieldColumn]);
}
}
if (count($update) > 0) {
if (php7_count($update) > 0) {
$sql1 = "UPDATE $table_name SET " . implode(",", $update) . " WHERE " . $this->tab_name_index[$table_name] . "=?";
array_push($update_params, $this->id);
if(Vtiger_Functions::isUserSpecificFieldTable($table_name, $module)){
......@@ -725,6 +780,7 @@ class CRMEntity {
*/
function deleteRelation($table_name) {
global $adb;
$table_name = Vtiger_Util_Helper::validateStringForSql($table_name);
$check_query = "select * from $table_name where " . $this->tab_name_index[$table_name] . "=?";
$check_result = $adb->pquery($check_query, array($this->id));
$num_rows = $adb->num_rows($check_result);
......@@ -889,7 +945,7 @@ class CRMEntity {
$entityFields = Vtiger_Functions::getEntityModuleInfo($module);
if(!empty($entityFields['fieldname'])) {
$entityFieldNames = explode(',', $entityFields['fieldname']);
if(count($entityFieldNames) > 1) {
if(php7_count($entityFieldNames) > 1) {
$this->column_fields['label'] = $resultrow[$entityFields['tablename'].$entityFieldNames[0]].' '.$resultrow[$entityFields['tablename'].$entityFieldNames[1]];
} else {
$this->column_fields['label'] = $resultrow[$entityFields['tablename'].$entityFieldNames[0]];
......@@ -903,12 +959,28 @@ class CRMEntity {
if (isset($resultrow[$fieldkey])) {
$fieldvalue = $resultrow[$fieldkey];
}
// load picklist value with umlatus with explict decoding
// required for field-value strict check during save.
if ($fieldinfo["uitype"] == 15 || $fieldinfo["uitype"] == 16) {
$fieldvalue = decode_html($fieldvalue);
}
$this->column_fields[$fieldinfo['fieldname']] = $fieldvalue;
}
}
}
//adding tags for vtws_retieve
$tagsList = Vtiger_Tag_Model::getAllAccessible($current_user->id, $module, $record);
$tags = array();
foreach($tagsList as $tag) {
$tags[] = $tag->getName();
}
$this->column_fields['tags'] = (php7_count($tags) > 0) ? implode(',',$tags) : '';
$this->column_fields['record_id'] = $record;
$this->id = $record;
$this->column_fields['record_module'] = $module;
$this->column_fields->startTracking();
}
......@@ -922,7 +994,7 @@ class CRMEntity {
//Event triggering code
require_once("include/events/include.inc");
$em = null;
//In Bulk mode stop triggering events
if(!self::isBulkSaveMode()) {
$em = new VTEventsManager($adb);
......@@ -933,7 +1005,7 @@ class CRMEntity {
$em->triggerEvent("vtiger.entity.beforesave.modifiable", $entityData);
$em->triggerEvent("vtiger.entity.beforesave", $entityData);
$em->triggerEvent("vtiger.entity.beforesave.final", $entityData);
}
}
//Event triggering code ends
//GS Save entity being called with the modulename as parameter
......@@ -1325,7 +1397,7 @@ class CRMEntity {
for ($k = 0; $k < $numOfRelRecords; $k++) {
$recordIdsList[] = $this->db->query_result($relResult, $k, $focusObj->table_index);
}
if(count($recordIdsList) > 0) {
if(php7_count($recordIdsList) > 0) {
$params = array($id, RB_RECORD_UPDATED, $tableName, $columnName, $focusObj->table_index, implode(",", $recordIdsList));
$this->db->pquery('INSERT INTO vtiger_relatedlists_rb VALUES (?,?,?,?,?,?)', $params);
}
......@@ -1451,11 +1523,11 @@ class CRMEntity {
" WHERE (fieldname not like '%\_id' OR fieldname in ('assigned_user_id'))" .
" AND tabid in (" . generateQuestionMarks($tabid) . ") and vtiger_field.presence in (0,2)";
$params = array($tabid);
if (count($exclude_columns) > 0) {
if (php7_count($exclude_columns) > 0) {
$sql .= " AND columnname NOT IN (" . generateQuestionMarks($exclude_columns) . ")";
array_push($params, $exclude_columns);
}
if (count($exclude_uitypes) > 0) {
if (php7_count($exclude_uitypes) > 0) {
$sql .= " AND uitype NOT IN (" . generateQuestionMarks($exclude_uitypes) . ")";
array_push($params, $exclude_uitypes);
}
......@@ -1540,6 +1612,8 @@ class CRMEntity {
/* Function to check if the mod number already exits */
function checkModuleSeqNumber($table, $column, $no) {
global $adb;
$table = Vtiger_Util_Helper::validateStringForSql($table);
$column = Vtiger_Util_Helper::validateStringForSql($column);
$result = $adb->pquery("select " . $adb->sql_escape_string($column) .
" from " . $adb->sql_escape_string($table) .
" where " . $adb->sql_escape_string($column) . " = ?", array($no));
......@@ -1576,8 +1650,8 @@ class CRMEntity {
$fld_column = $adb->query_result($fieldinfo, 0, 'columnname');
if ($fld_table == $this->table_name) {
$records = $adb->query("SELECT $this->table_index AS recordid FROM $this->table_name " .
"WHERE $fld_column = '' OR $fld_column is NULL");
$records = $adb->pquery("SELECT $this->table_index AS recordid FROM $this->table_name " .
"WHERE $fld_column = '' OR $fld_column is NULL", array());
if ($records && $adb->num_rows($records)) {
$returninfo['totalrecords'] = $adb->num_rows($records);
......@@ -1591,7 +1665,7 @@ class CRMEntity {
while ($recordinfo = $adb->fetch_array($records)) {
$value = "$prefix" . "$cur_id";
$adb->pquery("UPDATE $fld_table SET $fld_column = ? WHERE $this->table_index = ?", Array($value, $recordinfo['recordid']));
$cur_id += 1;
$cur_id = $this->getSequnceNumber($cur_id);
$returninfo['updatedrecords'] = $returninfo['updatedrecords'] + 1;
}
if ($old_cur_id != $cur_id) {
......@@ -1604,6 +1678,15 @@ class CRMEntity {
}
return $returninfo;
}
function getSequnceNumber($curid){
$strip = strlen($curid) - strlen($curid + 1);
if ($strip < 0)
$strip = 0;
$temp = str_repeat("0", $strip);
$req_no = $temp . ($curid + 1);
return $req_no;
}
/* Generic function to get attachments in the related list of a given module */
......@@ -1965,7 +2048,7 @@ class CRMEntity {
*/
function transferRelatedRecords($module, $transferEntityIds, $entityId) {
global $adb, $log;
$log->debug("Entering function transferRelatedRecords ($module, $transferEntityIds, $entityId)");
$log->debug("Entering function transferRelatedRecords ($module, ".implode(',',$transferEntityIds).", $entityId)");
foreach ($transferEntityIds as $transferId) {
// Pick the records related to the entity to be transfered, but do not pick the once which are already related to the current entity.
......@@ -1987,8 +2070,31 @@ class CRMEntity {
$parmodule = $adb->query_result($parentRecords, $i, 'module');
$adb->pquery("UPDATE vtiger_crmentityrel SET relcrmid=? WHERE crmid=? AND module=? AND relcrmid=? AND relmodule=?", array($entityId, $parcrmid, $parmodule, $transferId, $module));
}
$adb->pquery("UPDATE vtiger_modcomments SET related_to = ? WHERE related_to = ?", array($entityId, $transferId));
}
//lookup anything in vtiger_fieldmodulerel table where relmodule = this module
$sql = "SELECT fieldid FROM vtiger_fieldmodulerel WHERE relmodule = ?";
$query = $adb->pquery($sql, [$module]);
$numRows = $adb->num_rows($query);
//this gives a list of related fields that relate to this module
for ($i = 0; $i < $numRows; $i++) {
$field = $adb->query_result($query, $i, 'fieldid');
//then for each field lookup the tablename and columnname
$sql2 = "SELECT * FROM vtiger_field WHERE fieldid = ?";
$query2 = $adb->pquery($sql2, [$field]);
$numRows2 = $adb->num_rows($query2);
for ($j = 0; $j < $numRows2; $j++) {
$table = $adb->query_result($query2, $j, 'tablename');
$column = $adb->query_result($query2, $j, 'columnname');
//loop through and update any entry in those table/columns that points to the old ID and update to point to the new ID
foreach ($transferEntityIds as $transferId) {
$sql3 = "UPDATE $table SET $column = ? WHERE $column = ?";
$query3 = $adb->pquery($sql3, [$entityId, $transferId]);
}
}
}
$log->debug("Exiting transferRelatedRecords...");
}
......@@ -2204,6 +2310,86 @@ class CRMEntity {
return $query;
}
function getReportsUiType10Query($module, $queryPlanner){
$adb = PearDatabase::getInstance();
$relquery = '';
$matrix = $queryPlanner->newDependencyMatrix();
$params = array($module);
if($module == "Calendar") {
array_push($params,"Events");
}
$fields_query = $adb->pquery("SELECT vtiger_field.fieldname,vtiger_field.tablename,vtiger_field.fieldid from vtiger_field INNER JOIN vtiger_tab on vtiger_tab.name IN (". generateQuestionMarks($params).") WHERE vtiger_tab.tabid=vtiger_field.tabid AND vtiger_field.uitype IN (10) AND vtiger_field.presence IN (0,2)", $params);
if ($adb->num_rows($fields_query) > 0) {
for ($i = 0; $i < $adb->num_rows($fields_query); $i++) {
$field_name = $adb->query_result($fields_query, $i, 'fieldname');
$field_id = $adb->query_result($fields_query, $i, 'fieldid');
$tab_name = $adb->query_result($fields_query, $i, 'tablename');
$ui10_modules_query = $adb->pquery("SELECT relmodule FROM vtiger_fieldmodulerel WHERE fieldid=?", array($field_id));
if ($adb->num_rows($ui10_modules_query) > 0) {
// Capture the forward table dependencies due to dynamic related-field
$crmentityRelModuleFieldTable = "vtiger_crmentityRel$module$field_id";
$crmentityRelModuleFieldTableDeps = array();
$calendarFlag = false;
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
if(vtlib_isModuleActive($rel_mod)) {
if($rel_mod == 'Calendar') {
$calendarFlag = true;
}
if($calendarFlag && $rel_mod == 'Events') {
continue;
}
$rel_obj = CRMEntity::getInstance($rel_mod);
vtlib_setup_modulevars($rel_mod, $rel_obj);
$rel_tab_name = $rel_obj->table_name;
$rel_tab_index = $rel_obj->table_index;
$crmentityRelModuleFieldTableDeps[] = $rel_tab_name . "Rel$module$field_id";
}
}
$matrix->setDependency($crmentityRelModuleFieldTable, $crmentityRelModuleFieldTableDeps);
$matrix->addDependency($tab_name, $crmentityRelModuleFieldTable);
if ($queryPlanner->requireTable($crmentityRelModuleFieldTable, $matrix)) {
$relquery.= " LEFT JOIN vtiger_crmentity AS $crmentityRelModuleFieldTable ON $crmentityRelModuleFieldTable.crmid = $tab_name.$field_name AND vtiger_crmentityRel$module$field_id.deleted=0";
}
$calendarFlag = false;
for ($j = 0; $j < $adb->num_rows($ui10_modules_query); $j++) {
$rel_mod = $adb->query_result($ui10_modules_query, $j, 'relmodule');
if(vtlib_isModuleActive($rel_mod)) {
if($rel_mod == 'Calendar') {
$calendarFlag = true;
}
if($calendarFlag && $rel_mod == 'Events') {
continue;
}
$rel_obj = CRMEntity::getInstance($rel_mod);
vtlib_setup_modulevars($rel_mod, $rel_obj);
$rel_tab_name = $rel_obj->table_name;
$rel_tab_index = $rel_obj->table_index;
$rel_tab_name_rel_module_table_alias = $rel_tab_name . "Rel$module$field_id";
if ($queryPlanner->requireTable($rel_tab_name_rel_module_table_alias)) {
$relquery.= " LEFT JOIN $rel_tab_name AS $rel_tab_name_rel_module_table_alias ON $rel_tab_name_rel_module_table_alias.$rel_tab_index = $crmentityRelModuleFieldTable.crmid";
}
}
}
}
}
}
return $relquery;
}
/*
* Function to get the security query part of a report
* @param - $module primary module name
......@@ -2227,7 +2413,7 @@ class CRMEntity {
where vtiger_role.parentrole like '" . $current_user_parent_role_seq . "::%') or vtiger_crmentity.smownerid
in(select shareduserid from vtiger_tmp_read_user_sharing_per
where userid=" . $current_user->id . " and tabid=" . $tabid . ") or (";
if (sizeof($current_user_groups) > 0) {
if (php7_sizeof($current_user_groups) > 0) {
$sec_query .= " vtiger_crmentity.smownerid in (" . implode(",", $current_user_groups) . ") or ";
}
$sec_query .= " vtiger_crmentity.smownerid in(select vtiger_tmp_read_group_sharing_per.sharedgroupid
......@@ -2251,7 +2437,7 @@ class CRMEntity {
$fields[] = $value;
}
$pritablename = $tables[0];
$sectablename = $tables[1];
$sectablename = isset($tables[1]) ? $tables[1] : '';
$prifieldname = $fields[0][0];
$secfieldname = $fields[0][1];
$tmpname = $pritablename . 'tmp' . $secmodule;
......@@ -2280,7 +2466,7 @@ class CRMEntity {
//remove the primary key since it will conflict with base table column name or else creating temporary table will fails for duplicate columns
//eg : vtiger_potential has potentialid and vtiger_potentialscf has same potentialid
unset($columns[array_search($modulecfindex,$columns)]);
if(count($columns) > 0) {
if(php7_count($columns) > 0) {
$cfSelectString = implode(',',$columns);
$selectColumns .= ','.$cfSelectString;
}
......@@ -2291,7 +2477,7 @@ class CRMEntity {
$secQuery = 'SELECT '.$selectColumns.' '.$secQueryFrom;
$secQueryTempTableQuery = $queryPlanner->registerTempTable($secQuery, array($column_name, $fields[1], $prifieldname),$secmodule);
$secQueryTempTableQuery = $queryPlanner->registerTempTable($secQuery, array($column_name, isset($fields[1]) ? $fields[1] : '', $prifieldname),$secmodule);
$query = '';
if ($pritablename == 'vtiger_crmentityrel') {
......@@ -2510,12 +2696,18 @@ class CRMEntity {
}
}
$query = "select crmid as id ";
$entityfields = getEntityField($module);
$querycolumnnames = implode(',', $lookupcolumns);
$entitycolumnnames = $entityfields['fieldname'];
$query = "select crmid as id, $querycolumnnames, $entitycolumnnames as name ";
if(!empty($querycolumnnames)){
$query .= ", $querycolumnnames";
}
if(!empty($entitycolumnnames)){
$query .= ", $entitycolumnnames as name ";
}
$query .= " FROM $this->table_name ";
$query .=" INNER JOIN vtiger_crmentity ON $this->table_name.$this->table_index = vtiger_crmentity.crmid AND deleted = 0 ";
$query .= " INNER JOIN vtiger_crmentity ON $this->table_name.$this->table_index = vtiger_crmentity.crmid AND deleted = 0 ";
//remove the base table
$LookupTable = array_unique($lookuptables);
......@@ -2532,7 +2724,7 @@ class CRMEntity {
if (!empty($lookupcolumns) && $value !== false) {
$query .=" WHERE ";
$i = 0;
$columnCount = count($lookupcolumns);
$columnCount = php7_count($lookupcolumns);
foreach ($lookupcolumns as $columnname) {
if (!empty($columnname)) {
if ($i == 0 || $i == ($columnCount))
......@@ -2591,7 +2783,7 @@ class CRMEntity {
"vtiger_user2role INNER JOIN vtiger_users ON vtiger_users.id=vtiger_user2role.userid " .
"INNER JOIN vtiger_role ON vtiger_role.roleid=vtiger_user2role.roleid WHERE " .
"vtiger_role.parentrole like '$parentRole::%')";
if (count($userGroups) > 0) {
if (php7_count($userGroups) > 0) {
$query .= $this->getNonAdminUserGroupAccessQuery($userGroups);
}
return $query;
......@@ -2602,7 +2794,7 @@ class CRMEntity {
* @param <type> $userGroups
*/
function getNonAdminUserGroupAccessQuery($userGroups) {
$query .= " UNION (SELECT groupid FROM vtiger_groups WHERE groupid IN (".implode(",", $userGroups)."))";
$query = " UNION (SELECT groupid FROM vtiger_groups WHERE groupid IN (".implode(",", $userGroups)."))";
return $query;
}
......@@ -2615,11 +2807,11 @@ class CRMEntity {
require('user_privileges/sharing_privileges_' . $user->id . '.php');
$tabId = getTabid($module);
$sharingRuleInfoVariable = $module . '_share_read_permission';
$sharingRuleInfo = $$sharingRuleInfoVariable;
$sharingRuleInfo = isset($$sharingRuleInfoVariable) ? $$sharingRuleInfoVariable : array();
$sharedTabId = null;
$query = '';
if (!empty($sharingRuleInfo) && (count($sharingRuleInfo['ROLE']) > 0 ||
count($sharingRuleInfo['GROUP']) > 0)) {
if (!empty($sharingRuleInfo) && (php7_count($sharingRuleInfo['ROLE']) > 0 ||
php7_count($sharingRuleInfo['GROUP']) > 0)) {
$query = " (SELECT shareduserid FROM vtiger_tmp_read_user_sharing_per " .
"WHERE userid=$user->id AND tabid=$tabId) UNION (SELECT " .
"vtiger_tmp_read_group_sharing_per.sharedgroupid FROM " .
......@@ -2641,6 +2833,7 @@ class CRMEntity {
$module = getTabModuleName($tabId);
}
$query = $this->getNonAdminAccessQuery($module, $user, $parentRole, $userGroups);
$tableName = Vtiger_Util_Helper::validateStringForSql($tableName);
$query = "create temporary table IF NOT EXISTS $tableName(id int(11) primary key) ignore " .
$query;
$db = PearDatabase::getInstance();
......@@ -2668,8 +2861,8 @@ class CRMEntity {
$sharingRuleInfoVariable = $module . '_share_read_permission';
$sharingRuleInfo = $$sharingRuleInfoVariable;
$sharedTabId = null;
if (!empty($sharingRuleInfo) && (count($sharingRuleInfo['ROLE']) > 0 ||
count($sharingRuleInfo['GROUP']) > 0)) {
if (!empty($sharingRuleInfo) && (php7_count($sharingRuleInfo['ROLE']) > 0 ||
php7_count($sharingRuleInfo['GROUP']) > 0)) {
$tableName = $tableName . '_t' . $tabId;
$sharedTabId = $tabId;
} elseif ($module == 'Calendar' || !empty($scope)) {
......@@ -2786,11 +2979,11 @@ class CRMEntity {
$list_buttons = Array();
if (isPermitted($currentModule, 'Delete', '') == 'yes')
$list_buttons['del'] = $app_strings[LBL_MASS_DELETE];
$list_buttons['del'] = $app_strings["LBL_MASS_DELETE"];
if (isPermitted($currentModule, 'EditView', '') == 'yes') {
$list_buttons['mass_edit'] = $app_strings[LBL_MASS_EDIT];
$list_buttons['mass_edit'] = $app_strings["LBL_MASS_EDIT"];
// Mass Edit could be used to change the owner as well!
//$list_buttons['c_owner'] = $app_strings[LBL_CHANGE_OWNER];
//$list_buttons['c_owner'] = $app_strings["LBL_CHANGE_OWNER"];
}
return $list_buttons;
}
......@@ -2820,9 +3013,11 @@ class CRMEntity {
* @param <String> $selectedColumns
* @param <Boolean> $ignoreEmpty
* @param <Array> $requiredTables
* @param <Array> $columnTypes
* @return string
*/
function getQueryForDuplicates($module, $tableColumns, $selectedColumns = '', $ignoreEmpty = false,$requiredTables = array()) {
function getQueryForDuplicates($module, $tableColumns, $selectedColumns = '', $ignoreEmpty = false,$requiredTables = array(),$columnTypes = null) {
$query='';
if(is_array($tableColumns)) {
$tableColumnsString = implode(',', $tableColumns);
}
......@@ -2852,7 +3047,11 @@ class CRMEntity {
if($ignoreEmpty) {
foreach($tableColumns as $tableColumn){
$whereClause .= " AND ($tableColumn IS NOT NULL AND $tableColumn != '') ";
if ($columnTypes && ($columnTypes[$tableColumn] == "date" || $columnTypes[$tableColumn] == "datetime")) {
$whereClause .= " AND ($tableColumn IS NOT NULL) ";
} else {
$whereClause .= " AND ($tableColumn IS NOT NULL AND $tableColumn != '') ";
}
}
}
......@@ -2869,10 +3068,11 @@ class CRMEntity {
}
$i = 1;
$duplicateCheckClause='';
foreach($tableColumns as $tableColumn){
$tableInfo = explode('.', $tableColumn);
$duplicateCheckClause .= " ifnull($tableColumn,'null') = ifnull(temp.$tableInfo[1],'null')";
if (count($tableColumns) != $i++) $duplicateCheckClause .= " AND ";
if (php7_count($tableColumns) != $i++) $duplicateCheckClause .= " AND ";
}
$query = $selectClause . $fromClause .
......@@ -2933,6 +3133,7 @@ class CRMEntity {
}
}
#[\AllowDynamicProperties]
class TrackableObject implements ArrayAccess, IteratorAggregate {
private $storage;
private $trackingEnabled = true;
......@@ -2942,11 +3143,14 @@ class TrackableObject implements ArrayAccess, IteratorAggregate {
$this->storage = $value;
}
#[\ReturnTypeWillChange]
function offsetExists($key) {
return isset($this->storage[$key]);
return isset($this->storage[$key]) || array_key_exists($key, $this->storage);
}
#[\ReturnTypeWillChange]
function offsetSet($key, $value) {
if(is_array($value)) $value = empty($value) ? "" : (array_key_exists(0, $value) ? $value[0] : ""); //it is an associative (if array without a key 0) modified to prevent warning of Undefined array key 0 .
if($this->tracking && $this->trackingEnabled) {
$olderValue = $this->offsetGet($key);
// decode_html only expects string
......@@ -2959,14 +3163,17 @@ class TrackableObject implements ArrayAccess, IteratorAggregate {
$this->storage[$key] = $value;
}
#[\ReturnTypeWillChange]
public function offsetUnset($key) {
unset($this->storage[$key]);
}
#[\ReturnTypeWillChange]
public function offsetGet($key) {
return isset($this->storage[$key]) ? $this->storage[$key] : null;
return isset($this->storage[$key]) || array_key_exists($key, $this->storage) ? $this->storage[$key] : null;
}
#[\ReturnTypeWillChange]
public function getIterator() {
$iterator = new ArrayObject($this->storage);
return $iterator->getIterator();
......