forked from Wavyzz/dolibarr
Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop
This commit is contained in:
@@ -8,14 +8,10 @@ charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
[*.php]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
[*.js]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
indent_style = tab
|
||||
[*.css]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
indent_style = tab
|
||||
[*.xml]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
|
||||
@@ -18,6 +18,7 @@ CKEditor 4.3.3 LGPL-2.1+ Yes
|
||||
FPDI 1.5.2 Apache Software License 2.0 Yes PDF templates management
|
||||
GeoIP 1.4 LGPL-2.1+ Yes Sample code to make geoip convert (not into deb package)
|
||||
NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package)
|
||||
PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency
|
||||
odtPHP 1.0.1 GPL-2+ b Yes Library to build/edit ODT files
|
||||
PHPExcel 1.8.0 LGPL-2.1+ Yes Read/Write XLS files, read ODS files
|
||||
php-iban 1.4.6 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP
|
||||
|
||||
@@ -164,7 +164,7 @@ print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
print '<tr '.$bc[$var].' id="tramount"><td>';
|
||||
print $langs->trans("DefaultAmount");
|
||||
print '</td><td align="right">';
|
||||
print '<input type="text" id="MEMBER_NEWFORM_AMOUNT" name="MEMBER_NEWFORM_AMOUNT" size="5" value="'.(! empty($conf->global->MEMBER_NEWFORM_AMOUNT)?$conf->global->MEMBER_NEWFORM_AMOUNT:'').'">';;
|
||||
print '<input type="text" id="MEMBER_NEWFORM_AMOUNT" name="MEMBER_NEWFORM_AMOUNT" size="5" value="'.(! empty($conf->global->MEMBER_NEWFORM_AMOUNT)?$conf->global->MEMBER_NEWFORM_AMOUNT:'').'">';
|
||||
print "</td></tr>\n";
|
||||
|
||||
// Can edit
|
||||
@@ -197,7 +197,7 @@ if (! empty($conf->paybox->enabled) || ! empty($conf->paypal->enabled))
|
||||
print '<tr '.$bc[$var].' id="tremail"><td>';
|
||||
print $langs->trans("MEMBER_PAYONLINE_SENDEMAIL");
|
||||
print '</td><td align="right">';
|
||||
print '<input type="text" id="MEMBER_PAYONLINE_SENDEMAIL" name="MEMBER_PAYONLINE_SENDEMAIL" size="24" value="'.(! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL)?$conf->global->MEMBER_PAYONLINE_SENDEMAIL:'').'">';;
|
||||
print '<input type="text" id="MEMBER_PAYONLINE_SENDEMAIL" name="MEMBER_PAYONLINE_SENDEMAIL" size="24" value="'.(! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL)?$conf->global->MEMBER_PAYONLINE_SENDEMAIL:'').'">';
|
||||
print "</td></tr>\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ if (empty($reshook))
|
||||
}
|
||||
$lastname=$_POST["lastname"];
|
||||
$firstname=$_POST["firstname"];
|
||||
$morphy=$morphy=$_POST["morphy"];;
|
||||
$morphy=$morphy=$_POST["morphy"];
|
||||
if ($morphy != 'mor' && empty($lastname)) {
|
||||
$error++;
|
||||
$langs->load("errors");
|
||||
|
||||
@@ -369,7 +369,7 @@ if ($action == 'edit' || $action == 'updateedit')
|
||||
// Logo
|
||||
$var=!$var;
|
||||
print '<tr'.dol_bc($var,'hideonsmartphone').'><td><label for="logo">'.$langs->trans("Logo").' (png,jpg)</label></td><td>';
|
||||
print '<table width="100%" class="nocellnopadd"><tr class="nocellnopadd"><td valign="middle" class="nocellnopadd">';
|
||||
print '<table width="100%" class="nobordernopadding"><tr class="nocellnopadd"><td valign="middle" class="nocellnopadd">';
|
||||
print '<input type="file" class="flat" name="logo" id="logo" size="50">';
|
||||
print '</td><td valign="middle" align="right">';
|
||||
if (! empty($mysoc->logo_mini))
|
||||
@@ -754,7 +754,7 @@ else
|
||||
$var=!$var;
|
||||
print '<tr '.$bc[$var].'><td width="35%">'.$langs->trans("Logo").'</td><td>';
|
||||
|
||||
print '<table width="100%" class="nocellnopadd"><tr class="nocellnopadd"><td valign="middle" class="nocellnopadd">';
|
||||
print '<table width="100%" class="nobordernopadding"><tr class="nocellnopadd"><td valign="middle" class="nocellnopadd">';
|
||||
print $mysoc->logo;
|
||||
print '</td><td valign="center" align="right">';
|
||||
|
||||
|
||||
@@ -913,7 +913,7 @@ if ($id)
|
||||
print "</tr>";
|
||||
|
||||
$colspan=count($fieldlist)+2;
|
||||
if ($id == 4) $colspan++;;
|
||||
if ($id == 4) $colspan++;
|
||||
|
||||
if (! empty($alabelisused)) // Si un des champs est un libelle
|
||||
{
|
||||
|
||||
@@ -164,7 +164,7 @@ if (! empty($conf->service->enabled))
|
||||
$var=! $var;
|
||||
print '<tr '.$bc[$var].'><td>';
|
||||
print $langs->trans("CashdeskShowServices");
|
||||
print '<td colspan="2">';;
|
||||
print '<td colspan="2">';
|
||||
print $form->selectyesno("CASHDESK_SERVICES",$conf->global->CASHDESK_SERVICES,1);
|
||||
print "</td></tr>\n";
|
||||
}
|
||||
|
||||
@@ -1164,7 +1164,7 @@ class Categorie extends CommonObject
|
||||
{
|
||||
$cats = array();
|
||||
|
||||
$typeid=-1; $table='';;
|
||||
$typeid=-1; $table='';
|
||||
if ($type == '0' || $type == 'product') { $typeid=0; $table='product'; $type='product'; }
|
||||
else if ($type == '1' || $type == 'supplier') { $typeid=1; $table='societe'; $type='fournisseur'; }
|
||||
else if ($type == '2' || $type == 'customer') { $typeid=2; $table='societe'; $type='societe'; }
|
||||
|
||||
@@ -379,7 +379,7 @@ else
|
||||
elseif ($links[$key]['type']=='payment_supplier')
|
||||
{
|
||||
$paymentsupplierstatic->id=$links[$key]['url_id'];
|
||||
$paymentsupplierstatic->ref=$langs->trans("Payment");;
|
||||
$paymentsupplierstatic->ref=$langs->trans("Payment");
|
||||
print ' '.$paymentsupplierstatic->getNomUrl(1);
|
||||
$newline=0;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ for ($mois = 1+$nb_mois_decalage ; $mois <= 12+$nb_mois_decalage ; $mois++)
|
||||
if ($annee_decalage != $year_end) print '<td width="15"> </td>';
|
||||
}
|
||||
|
||||
$total_ht[$annee]+=!empty($cum_ht[$case]) ? $cum_ht[$case] : 0;;
|
||||
$total_ht[$annee]+=!empty($cum_ht[$case]) ? $cum_ht[$case] : 0;
|
||||
$total[$annee]+=$cum[$case];
|
||||
}
|
||||
|
||||
|
||||
@@ -837,15 +837,15 @@ class FormMail extends Form
|
||||
if ($resql)
|
||||
{
|
||||
$this->lines_model=array();
|
||||
while ($obj = $this->db->fetch_object($resql)) {
|
||||
$line = new ModelMailLine();
|
||||
while ($obj = $this->db->fetch_object($resql))
|
||||
{
|
||||
$line = new ModelMail();
|
||||
$line->id=$obj->rowid;
|
||||
$line->label=$obj->label;
|
||||
$line->topic=$obj->topic;
|
||||
$line->content=$obj->lacontentbel;
|
||||
$line->lang=$obj->lang;
|
||||
$this->lines_model[]=$line;
|
||||
|
||||
}
|
||||
$this->db->free($resql);
|
||||
return $num;
|
||||
@@ -858,7 +858,10 @@ class FormMail extends Form
|
||||
}
|
||||
}
|
||||
|
||||
class ModelMailLine
|
||||
/**
|
||||
* ModelMail
|
||||
*/
|
||||
class ModelMail
|
||||
{
|
||||
public $id;
|
||||
public $label;
|
||||
|
||||
@@ -231,7 +231,7 @@ function dol_getshmop($memoryid)
|
||||
global $shmkeys,$shmoffset;
|
||||
|
||||
if (empty($shmkeys[$memoryid]) || ! function_exists("shmop_open")) return 0;
|
||||
$shmkey=dol_getshmopaddress($memoryid);;
|
||||
$shmkey=dol_getshmopaddress($memoryid);
|
||||
//print 'dol_getshmop memoryid='.$memoryid." shmkey=".$shmkey."<br>\n";
|
||||
$handle=@shmop_open($shmkey,'a',0,0);
|
||||
if ($handle)
|
||||
|
||||
@@ -117,17 +117,17 @@ function task_prepare_head($object)
|
||||
$h = 0;
|
||||
$head = array();
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/task.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');;
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/task.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
|
||||
$head[$h][1] = $langs->trans("Card");
|
||||
$head[$h][2] = 'task_task';
|
||||
$h++;
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/contact.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');;
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/contact.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
|
||||
$head[$h][1] = $langs->trans("TaskRessourceLinks");
|
||||
$head[$h][2] = 'task_contact';
|
||||
$h++;
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/time.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');;
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/time.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
|
||||
$head[$h][1] = $langs->trans("TimeSpent");
|
||||
$head[$h][2] = 'task_time';
|
||||
$h++;
|
||||
@@ -143,14 +143,14 @@ function task_prepare_head($object)
|
||||
$nbNote = 0;
|
||||
if(!empty($object->note_private)) $nbNote++;
|
||||
if(!empty($object->note_public)) $nbNote++;
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/note.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');;
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/note.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
|
||||
$head[$h][1] = $langs->trans('Notes');
|
||||
if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>';
|
||||
$head[$h][2] = 'task_notes';
|
||||
$h++;
|
||||
}
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/document.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');;
|
||||
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/document.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
|
||||
$filesdir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($object->project->ref) . '/' .dol_sanitizeFileName($object->ref);
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
$listoffiles=dol_dir_list($filesdir,'files',1,'','thumbs');
|
||||
|
||||
@@ -496,7 +496,7 @@ function vat_by_date($db, $y, $q, $date_start, $date_end, $modetax, $direction,
|
||||
$sql.= " AND f.fk_statut in (1,2)"; // Paid (partially or completely)
|
||||
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
|
||||
else $sql.= " AND f.type IN (0,1,2,3,5)";
|
||||
$sql.= " AND f.rowid = d.".$fk_facture;;
|
||||
$sql.= " AND f.rowid = d.".$fk_facture;
|
||||
$sql.= " AND pf.".$fk_facture2." = f.rowid";
|
||||
$sql.= " AND pa.rowid = pf.".$fk_payment;
|
||||
if ($y && $m)
|
||||
|
||||
@@ -376,7 +376,7 @@ class ImportCsv extends ModeleImports
|
||||
if ($obj) $tablewithentity_cache[$tablename]=1; // table contains entity field
|
||||
else $tablewithentity_cache[$tablename]=0; // table does not contains entity field
|
||||
}
|
||||
else dol_print_error($this->db);;
|
||||
else dol_print_error($this->db);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -416,7 +416,7 @@ class doc_generic_task_odt extends ModelePDFTask
|
||||
$project= new Project($this->db);
|
||||
$project->fetch($object->fk_project);
|
||||
|
||||
$dir = $conf->projet->dir_output. "/" . $project->ref. "/";;
|
||||
$dir = $conf->projet->dir_output. "/" . $project->ref. "/";
|
||||
$objectref = dol_sanitizeFileName($object->ref);
|
||||
if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref;
|
||||
$file = $dir . "/" . $objectref . ".odt";
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
else if (type == 'boolean') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").hide();jQuery("#helpchkbxlst").hide();}
|
||||
else if (type == 'price') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").hide();jQuery("#helpchkbxlst").hide();}
|
||||
else if (type == 'select') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").show();jQuery("#helpselect").show();jQuery("#helpsellist").hide();jQuery("#helpchkbxlst").hide();jQuery("#helplink").hide();}
|
||||
else if (type == 'link') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").show();jQuery("#helpselect").hide();jQuery("#helpsellist").hide();;jQuery("#helpchkbxlst").hide();jQuery("#helplink").show();}
|
||||
else if (type == 'link') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").show();jQuery("#helpselect").hide();jQuery("#helpsellist").hide();jQuery("#helpchkbxlst").hide();jQuery("#helplink").show();}
|
||||
else if (type == 'sellist') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").show();jQuery("#helpselect").hide();jQuery("#helpsellist").show();jQuery("#helpchkbxlst").hide();jQuery("#helplink").hide();}
|
||||
else if (type == 'radio') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").show();jQuery("#helpselect").show();jQuery("#helpsellist").hide();jQuery("#helpchkbxlst").hide();jQuery("#helplink").hide();}
|
||||
else if (type == 'checkbox') { size.val('').attr('disabled','disabled'); unique.attr('disabled','disabled'); jQuery("#value_choice").show();jQuery("#helpselect").show();jQuery("#helpsellist").hide();jQuery("#helpchkbxlst").hide();jQuery("#helplink").hide();}
|
||||
|
||||
@@ -623,7 +623,7 @@ class ExpenseReport extends CommonObject
|
||||
print $langs->trans('Draft').' '.img_picto($langs->trans('Draft'),'statut0');
|
||||
break;
|
||||
case 2:
|
||||
print $langs->trans('TripForValid').' '.img_picto($langs->trans('TripForValid'),'statut3');;
|
||||
print $langs->trans('TripForValid').' '.img_picto($langs->trans('TripForValid'),'statut3');
|
||||
break;
|
||||
case 5:
|
||||
print $langs->trans('TripForPaid').' '.img_picto($langs->trans('TripForPaid'),'statut3');
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,922 +0,0 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2001-2002, Richard Heyes |
|
||||
// | All rights reserved. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | o Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | o Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution.|
|
||||
// | o The names of the authors may not be used to endorse or promote |
|
||||
// | products derived from this software without specific prior written |
|
||||
// | permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
||||
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
||||
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
||||
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
||||
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||
// | |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Authors: Richard Heyes <richard@phpguru.org> |
|
||||
// | Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* RFC 822 Email address list validation Utility
|
||||
*
|
||||
* What is it?
|
||||
*
|
||||
* This class will take an address string, and parse it into it's consituent
|
||||
* parts, be that either addresses, groups, or combinations. Nested groups
|
||||
* are not supported. The structure it returns is pretty straight forward,
|
||||
* and is similar to that provided by the imap_rfc822_parse_adrlist(). Use
|
||||
* print_r() to view the structure.
|
||||
*
|
||||
* How do I use it?
|
||||
*
|
||||
* $address_string = 'My Group: "Richard" <richard@localhost> (A comment), ted@example.com (Ted Bloggs), Barney;';
|
||||
* $structure = Mail_RFC822::parseAddressList($address_string, 'example.com', true)
|
||||
* print_r($structure);
|
||||
*
|
||||
* @author Richard Heyes <richard@phpguru.org>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @license BSD
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail_RFC822 {
|
||||
|
||||
/**
|
||||
* The address being parsed by the RFC822 object.
|
||||
* @var string $address
|
||||
*/
|
||||
var $address = '';
|
||||
|
||||
/**
|
||||
* The default domain to use for unqualified addresses.
|
||||
* @var string $default_domain
|
||||
*/
|
||||
var $default_domain = 'localhost';
|
||||
|
||||
/**
|
||||
* Should we return a nested array showing groups, or flatten everything?
|
||||
* @var boolean $nestGroups
|
||||
*/
|
||||
var $nestGroups = true;
|
||||
|
||||
/**
|
||||
* Whether or not to validate atoms for non-ascii characters.
|
||||
* @var boolean $validate
|
||||
*/
|
||||
var $validate = true;
|
||||
|
||||
/**
|
||||
* The array of raw addresses built up as we parse.
|
||||
* @var array $addresses
|
||||
*/
|
||||
var $addresses = array();
|
||||
|
||||
/**
|
||||
* The final array of parsed address information that we build up.
|
||||
* @var array $structure
|
||||
*/
|
||||
var $structure = array();
|
||||
|
||||
/**
|
||||
* The current error message, if any.
|
||||
* @var string $error
|
||||
*/
|
||||
var $error = null;
|
||||
|
||||
/**
|
||||
* An internal counter/pointer.
|
||||
* @var integer $index
|
||||
*/
|
||||
var $index = null;
|
||||
|
||||
/**
|
||||
* The number of groups that have been found in the address list.
|
||||
* @var integer $num_groups
|
||||
* @access public
|
||||
*/
|
||||
var $num_groups = 0;
|
||||
|
||||
/**
|
||||
* A variable so that we can tell whether or not we're inside a
|
||||
* Mail_RFC822 object.
|
||||
* @var boolean $mailRFC822
|
||||
*/
|
||||
var $mailRFC822 = true;
|
||||
|
||||
/**
|
||||
* A limit after which processing stops
|
||||
* @var int $limit
|
||||
*/
|
||||
var $limit = null;
|
||||
|
||||
/**
|
||||
* Sets up the object. The address must either be set here or when
|
||||
* calling parseAddressList(). One or the other.
|
||||
*
|
||||
* @access public
|
||||
* @param string $address The address(es) to validate.
|
||||
* @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost.
|
||||
* @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
|
||||
* @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
|
||||
*
|
||||
* @return object Mail_RFC822 A new Mail_RFC822 object.
|
||||
*/
|
||||
function Mail_RFC822($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
|
||||
{
|
||||
if (isset($address)) $this->address = $address;
|
||||
if (isset($default_domain)) $this->default_domain = $default_domain;
|
||||
if (isset($nest_groups)) $this->nestGroups = $nest_groups;
|
||||
if (isset($validate)) $this->validate = $validate;
|
||||
if (isset($limit)) $this->limit = $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the whole process. The address must either be set here
|
||||
* or when creating the object. One or the other.
|
||||
*
|
||||
* @access public
|
||||
* @param string $address The address(es) to validate.
|
||||
* @param string $default_domain Default domain/host etc.
|
||||
* @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
|
||||
* @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
|
||||
*
|
||||
* @return array A structured array of addresses.
|
||||
*/
|
||||
function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
|
||||
{
|
||||
if (!isset($this) || !isset($this->mailRFC822)) {
|
||||
$obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit);
|
||||
return $obj->parseAddressList();
|
||||
}
|
||||
|
||||
if (isset($address)) $this->address = $address;
|
||||
if (isset($default_domain)) $this->default_domain = $default_domain;
|
||||
if (isset($nest_groups)) $this->nestGroups = $nest_groups;
|
||||
if (isset($validate)) $this->validate = $validate;
|
||||
if (isset($limit)) $this->limit = $limit;
|
||||
|
||||
$this->structure = array();
|
||||
$this->addresses = array();
|
||||
$this->error = null;
|
||||
$this->index = null;
|
||||
|
||||
// Unfold any long lines in $this->address.
|
||||
$this->address = preg_replace('/\r?\n/', "\r\n", $this->address);
|
||||
$this->address = preg_replace('/\r\n(\t| )+/', ' ', $this->address);
|
||||
|
||||
while ($this->address = $this->_splitAddresses($this->address));
|
||||
|
||||
if ($this->address === false || isset($this->error)) {
|
||||
require_once 'PEAR.php';
|
||||
return PEAR::raiseError($this->error);
|
||||
}
|
||||
|
||||
// Validate each address individually. If we encounter an invalid
|
||||
// address, stop iterating and return an error immediately.
|
||||
foreach ($this->addresses as $address) {
|
||||
$valid = $this->_validateAddress($address);
|
||||
|
||||
if ($valid === false || isset($this->error)) {
|
||||
require_once 'PEAR.php';
|
||||
return PEAR::raiseError($this->error);
|
||||
}
|
||||
|
||||
if (!$this->nestGroups) {
|
||||
$this->structure = array_merge($this->structure, $valid);
|
||||
} else {
|
||||
$this->structure[] = $valid;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an address into separate addresses.
|
||||
*
|
||||
* @access private
|
||||
* @param string $address The addresses to split.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _splitAddresses($address)
|
||||
{
|
||||
if (!empty($this->limit) && count($this->addresses) == $this->limit) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->_isGroup($address) && !isset($this->error)) {
|
||||
$split_char = ';';
|
||||
$is_group = true;
|
||||
} elseif (!isset($this->error)) {
|
||||
$split_char = ',';
|
||||
$is_group = false;
|
||||
} elseif (isset($this->error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Split the string based on the above ten or so lines.
|
||||
$parts = explode($split_char, $address);
|
||||
$string = $this->_splitCheck($parts, $split_char);
|
||||
|
||||
// If a group...
|
||||
if ($is_group) {
|
||||
// If $string does not contain a colon outside of
|
||||
// brackets/quotes etc then something's fubar.
|
||||
|
||||
// First check there's a colon at all:
|
||||
if (strpos($string, ':') === false) {
|
||||
$this->error = 'Invalid address: ' . $string;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now check it's outside of brackets/quotes:
|
||||
if (!$this->_splitCheck(explode(':', $string), ':')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We must have a group at this point, so increase the counter:
|
||||
$this->num_groups++;
|
||||
}
|
||||
|
||||
// $string now contains the first full address/group.
|
||||
// Add to the addresses array.
|
||||
$this->addresses[] = array(
|
||||
'address' => trim($string),
|
||||
'group' => $is_group
|
||||
);
|
||||
|
||||
// Remove the now stored address from the initial line, the +1
|
||||
// is to account for the explode character.
|
||||
$address = trim(substr($address, strlen($string) + 1));
|
||||
|
||||
// If the next char is a comma and this was a group, then
|
||||
// there are more addresses, otherwise, if there are any more
|
||||
// chars, then there is another address.
|
||||
if ($is_group && substr($address, 0, 1) == ','){
|
||||
$address = trim(substr($address, 1));
|
||||
return $address;
|
||||
|
||||
} elseif (strlen($address) > 0) {
|
||||
return $address;
|
||||
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
// If you got here then something's off
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a group at the start of the string.
|
||||
*
|
||||
* @access private
|
||||
* @param string $address The address to check.
|
||||
* @return boolean Whether or not there is a group at the start of the string.
|
||||
*/
|
||||
function _isGroup($address)
|
||||
{
|
||||
// First comma not in quotes, angles or escaped:
|
||||
$parts = explode(',', $address);
|
||||
$string = $this->_splitCheck($parts, ',');
|
||||
|
||||
// Now we have the first address, we can reliably check for a
|
||||
// group by searching for a colon that's not escaped or in
|
||||
// quotes or angle brackets.
|
||||
if (count($parts = explode(':', $string)) > 1) {
|
||||
$string2 = $this->_splitCheck($parts, ':');
|
||||
return ($string2 !== $string);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A common function that will check an exploded string.
|
||||
*
|
||||
* @access private
|
||||
* @param array $parts The exloded string.
|
||||
* @param string $char The char that was exploded on.
|
||||
* @return mixed False if the string contains unclosed quotes/brackets, or the string on success.
|
||||
*/
|
||||
function _splitCheck($parts, $char)
|
||||
{
|
||||
$string = $parts[0];
|
||||
|
||||
for ($i = 0; $i < count($parts); $i++) {
|
||||
if ($this->_hasUnclosedQuotes($string)
|
||||
|| $this->_hasUnclosedBrackets($string, '<>')
|
||||
|| $this->_hasUnclosedBrackets($string, '[]')
|
||||
|| $this->_hasUnclosedBrackets($string, '()')
|
||||
|| substr($string, -1) == '\\') {
|
||||
if (isset($parts[$i + 1])) {
|
||||
$string = $string . $char . $parts[$i + 1];
|
||||
} else {
|
||||
$this->error = 'Invalid address spec. Unclosed bracket or quotes';
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->index = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string has an unclosed quotes or not.
|
||||
*
|
||||
* @access private
|
||||
* @param string $string The string to check.
|
||||
* @return boolean True if there are unclosed quotes inside the string, false otherwise.
|
||||
*/
|
||||
function _hasUnclosedQuotes($string)
|
||||
{
|
||||
$string = explode('"', $string);
|
||||
$string_cnt = count($string);
|
||||
|
||||
for ($i = 0; $i < (count($string) - 1); $i++)
|
||||
if (substr($string[$i], -1) == '\\')
|
||||
$string_cnt--;
|
||||
|
||||
return ($string_cnt % 2 === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string has an unclosed brackets or not. IMPORTANT:
|
||||
* This function handles both angle brackets and square brackets;
|
||||
*
|
||||
* @access private
|
||||
* @param string $string The string to check.
|
||||
* @param string $chars The characters to check for.
|
||||
* @return boolean True if there are unclosed brackets inside the string, false otherwise.
|
||||
*/
|
||||
function _hasUnclosedBrackets($string, $chars)
|
||||
{
|
||||
$num_angle_start = substr_count($string, $chars[0]);
|
||||
$num_angle_end = substr_count($string, $chars[1]);
|
||||
|
||||
$this->_hasUnclosedBracketsSub($string, $num_angle_start, $chars[0]);
|
||||
$this->_hasUnclosedBracketsSub($string, $num_angle_end, $chars[1]);
|
||||
|
||||
if ($num_angle_start < $num_angle_end) {
|
||||
$this->error = 'Invalid address spec. Unmatched quote or bracket (' . $chars . ')';
|
||||
return false;
|
||||
} else {
|
||||
return ($num_angle_start > $num_angle_end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub function that is used only by hasUnclosedBrackets().
|
||||
*
|
||||
* @access private
|
||||
* @param string $string The string to check.
|
||||
* @param integer &$num The number of occurences.
|
||||
* @param string $char The character to count.
|
||||
* @return integer The number of occurences of $char in $string, adjusted for backslashes.
|
||||
*/
|
||||
function _hasUnclosedBracketsSub($string, &$num, $char)
|
||||
{
|
||||
$parts = explode($char, $string);
|
||||
for ($i = 0; $i < count($parts); $i++){
|
||||
if (substr($parts[$i], -1) == '\\' || $this->_hasUnclosedQuotes($parts[$i]))
|
||||
$num--;
|
||||
if (isset($parts[$i + 1]))
|
||||
$parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1];
|
||||
}
|
||||
|
||||
return $num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to begin checking the address.
|
||||
*
|
||||
* @access private
|
||||
* @param string $address The address to validate.
|
||||
* @return mixed False on failure, or a structured array of address information on success.
|
||||
*/
|
||||
function _validateAddress($address)
|
||||
{
|
||||
$is_group = false;
|
||||
$addresses = array();
|
||||
|
||||
if ($address['group']) {
|
||||
$is_group = true;
|
||||
|
||||
// Get the group part of the name
|
||||
$parts = explode(':', $address['address']);
|
||||
$groupname = $this->_splitCheck($parts, ':');
|
||||
$structure = array();
|
||||
|
||||
// And validate the group part of the name.
|
||||
if (!$this->_validatePhrase($groupname)){
|
||||
$this->error = 'Group name did not validate.';
|
||||
return false;
|
||||
} else {
|
||||
// Don't include groups if we are not nesting
|
||||
// them. This avoids returning invalid addresses.
|
||||
if ($this->nestGroups) {
|
||||
$structure = new stdClass;
|
||||
$structure->groupname = $groupname;
|
||||
}
|
||||
}
|
||||
|
||||
$address['address'] = ltrim(substr($address['address'], strlen($groupname . ':')));
|
||||
}
|
||||
|
||||
// If a group then split on comma and put into an array.
|
||||
// Otherwise, Just put the whole address in an array.
|
||||
if ($is_group) {
|
||||
while (strlen($address['address']) > 0) {
|
||||
$parts = explode(',', $address['address']);
|
||||
$addresses[] = $this->_splitCheck($parts, ',');
|
||||
$address['address'] = trim(substr($address['address'], strlen(end($addresses) . ',')));
|
||||
}
|
||||
} else {
|
||||
$addresses[] = $address['address'];
|
||||
}
|
||||
|
||||
// Check that $addresses is set, if address like this:
|
||||
// Groupname:;
|
||||
// Then errors were appearing.
|
||||
if (!count($addresses)){
|
||||
$this->error = 'Empty group.';
|
||||
return false;
|
||||
}
|
||||
|
||||
// Trim the whitespace from all of the address strings.
|
||||
array_map('trim', $addresses);
|
||||
|
||||
// Validate each mailbox.
|
||||
// Format could be one of: name <geezer@domain.com>
|
||||
// geezer@domain.com
|
||||
// geezer
|
||||
// ... or any other format valid by RFC 822.
|
||||
for ($i = 0; $i < count($addresses); $i++) {
|
||||
if (!$this->validateMailbox($addresses[$i])) {
|
||||
if (empty($this->error)) {
|
||||
$this->error = 'Validation failed for: ' . $addresses[$i];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Nested format
|
||||
if ($this->nestGroups) {
|
||||
if ($is_group) {
|
||||
$structure->addresses = $addresses;
|
||||
} else {
|
||||
$structure = $addresses[0];
|
||||
}
|
||||
|
||||
// Flat format
|
||||
} else {
|
||||
if ($is_group) {
|
||||
$structure = array_merge($structure, $addresses);
|
||||
} else {
|
||||
$structure = $addresses;
|
||||
}
|
||||
}
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a phrase.
|
||||
*
|
||||
* @access private
|
||||
* @param string $phrase The phrase to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validatePhrase($phrase)
|
||||
{
|
||||
// Splits on one or more Tab or space.
|
||||
$parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$phrase_parts = array();
|
||||
while (count($parts) > 0){
|
||||
$phrase_parts[] = $this->_splitCheck($parts, ' ');
|
||||
for ($i = 0; $i < $this->index + 1; $i++)
|
||||
array_shift($parts);
|
||||
}
|
||||
|
||||
foreach ($phrase_parts as $part) {
|
||||
// If quoted string:
|
||||
if (substr($part, 0, 1) == '"') {
|
||||
if (!$this->_validateQuotedString($part)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise it's an atom:
|
||||
if (!$this->_validateAtom($part)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate an atom which from rfc822 is:
|
||||
* atom = 1*<any CHAR except specials, SPACE and CTLs>
|
||||
*
|
||||
* If validation ($this->validate) has been turned off, then
|
||||
* validateAtom() doesn't actually check anything. This is so that you
|
||||
* can split a list of addresses up before encoding personal names
|
||||
* (umlauts, etc.), for example.
|
||||
*
|
||||
* @access private
|
||||
* @param string $atom The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateAtom($atom)
|
||||
{
|
||||
if (!$this->validate) {
|
||||
// Validation has been turned off; assume the atom is okay.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for any char from ASCII 0 - ASCII 127
|
||||
if (!preg_match('/^[\\x00-\\x7E]+$/i', $atom, $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for specials:
|
||||
if (preg_match('/[][()<>@,;\\:". ]/', $atom)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for control characters (ASCII 0-31):
|
||||
if (preg_match('/[\\x00-\\x1F]+/', $atom)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate quoted string, which is:
|
||||
* quoted-string = <"> *(qtext/quoted-pair) <">
|
||||
*
|
||||
* @access private
|
||||
* @param string $qstring The string to check
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateQuotedString($qstring)
|
||||
{
|
||||
// Leading and trailing "
|
||||
$qstring = substr($qstring, 1, -1);
|
||||
|
||||
// Perform check, removing quoted characters first.
|
||||
return !preg_match('/[\x0D\\\\"]/', preg_replace('/\\\\./', '', $qstring));
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a mailbox, which is:
|
||||
* mailbox = addr-spec ; simple address
|
||||
* / phrase route-addr ; name and route-addr
|
||||
*
|
||||
* @access public
|
||||
* @param string &$mailbox The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function validateMailbox(&$mailbox)
|
||||
{
|
||||
// A couple of defaults.
|
||||
$phrase = '';
|
||||
$comment = '';
|
||||
$comments = array();
|
||||
|
||||
// Catch any RFC822 comments and store them separately.
|
||||
$_mailbox = $mailbox;
|
||||
while (strlen(trim($_mailbox)) > 0) {
|
||||
$parts = explode('(', $_mailbox);
|
||||
$before_comment = $this->_splitCheck($parts, '(');
|
||||
if ($before_comment != $_mailbox) {
|
||||
// First char should be a (.
|
||||
$comment = substr(str_replace($before_comment, '', $_mailbox), 1);
|
||||
$parts = explode(')', $comment);
|
||||
$comment = $this->_splitCheck($parts, ')');
|
||||
$comments[] = $comment;
|
||||
|
||||
// +1 is for the trailing )
|
||||
$_mailbox = substr($_mailbox, strpos($_mailbox, $comment)+strlen($comment)+1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($comments as $comment) {
|
||||
$mailbox = str_replace("($comment)", '', $mailbox);
|
||||
}
|
||||
|
||||
$mailbox = trim($mailbox);
|
||||
|
||||
// Check for name + route-addr
|
||||
if (substr($mailbox, -1) == '>' && substr($mailbox, 0, 1) != '<') {
|
||||
$parts = explode('<', $mailbox);
|
||||
$name = $this->_splitCheck($parts, '<');
|
||||
|
||||
$phrase = trim($name);
|
||||
$route_addr = trim(substr($mailbox, strlen($name.'<'), -1));
|
||||
|
||||
if ($this->_validatePhrase($phrase) === false || ($route_addr = $this->_validateRouteAddr($route_addr)) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only got addr-spec
|
||||
} else {
|
||||
// First snip angle brackets if present.
|
||||
if (substr($mailbox, 0, 1) == '<' && substr($mailbox, -1) == '>') {
|
||||
$addr_spec = substr($mailbox, 1, -1);
|
||||
} else {
|
||||
$addr_spec = $mailbox;
|
||||
}
|
||||
|
||||
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the object that will be returned.
|
||||
$mbox = new stdClass();
|
||||
|
||||
// Add the phrase (even if empty) and comments
|
||||
$mbox->personal = $phrase;
|
||||
$mbox->comment = isset($comments) ? $comments : array();
|
||||
|
||||
if (isset($route_addr)) {
|
||||
$mbox->mailbox = $route_addr['local_part'];
|
||||
$mbox->host = $route_addr['domain'];
|
||||
$route_addr['adl'] !== '' ? $mbox->adl = $route_addr['adl'] : '';
|
||||
} else {
|
||||
$mbox->mailbox = $addr_spec['local_part'];
|
||||
$mbox->host = $addr_spec['domain'];
|
||||
}
|
||||
|
||||
$mailbox = $mbox;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function validates a route-addr which is:
|
||||
* route-addr = "<" [route] addr-spec ">"
|
||||
*
|
||||
* Angle brackets have already been removed at the point of
|
||||
* getting to this function.
|
||||
*
|
||||
* @access private
|
||||
* @param string $route_addr The string to check.
|
||||
* @return mixed False on failure, or an array containing validated address/route information on success.
|
||||
*/
|
||||
function _validateRouteAddr($route_addr)
|
||||
{
|
||||
// Check for colon.
|
||||
if (strpos($route_addr, ':') !== false) {
|
||||
$parts = explode(':', $route_addr);
|
||||
$route = $this->_splitCheck($parts, ':');
|
||||
} else {
|
||||
$route = $route_addr;
|
||||
}
|
||||
|
||||
// If $route is same as $route_addr then the colon was in
|
||||
// quotes or brackets or, of course, non existent.
|
||||
if ($route === $route_addr){
|
||||
unset($route);
|
||||
$addr_spec = $route_addr;
|
||||
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Validate route part.
|
||||
if (($route = $this->_validateRoute($route)) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$addr_spec = substr($route_addr, strlen($route . ':'));
|
||||
|
||||
// Validate addr-spec part.
|
||||
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($route)) {
|
||||
$return['adl'] = $route;
|
||||
} else {
|
||||
$return['adl'] = '';
|
||||
}
|
||||
|
||||
$return = array_merge($return, $addr_spec);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a route, which is:
|
||||
* route = 1#("@" domain) ":"
|
||||
*
|
||||
* @access private
|
||||
* @param string $route The string to check.
|
||||
* @return mixed False on failure, or the validated $route on success.
|
||||
*/
|
||||
function _validateRoute($route)
|
||||
{
|
||||
// Split on comma.
|
||||
$domains = explode(',', trim($route));
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$domain = str_replace('@', '', trim($domain));
|
||||
if (!$this->_validateDomain($domain)) return false;
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a domain, though this is not quite what
|
||||
* you expect of a strict internet domain.
|
||||
*
|
||||
* domain = sub-domain *("." sub-domain)
|
||||
*
|
||||
* @access private
|
||||
* @param string $domain The string to check.
|
||||
* @return mixed False on failure, or the validated domain on success.
|
||||
*/
|
||||
function _validateDomain($domain)
|
||||
{
|
||||
// Note the different use of $subdomains and $sub_domains
|
||||
$subdomains = explode('.', $domain);
|
||||
|
||||
while (count($subdomains) > 0) {
|
||||
$sub_domains[] = $this->_splitCheck($subdomains, '.');
|
||||
for ($i = 0; $i < $this->index + 1; $i++)
|
||||
array_shift($subdomains);
|
||||
}
|
||||
|
||||
foreach ($sub_domains as $sub_domain) {
|
||||
if (!$this->_validateSubdomain(trim($sub_domain)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Managed to get here, so return input.
|
||||
return $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a subdomain:
|
||||
* subdomain = domain-ref / domain-literal
|
||||
*
|
||||
* @access private
|
||||
* @param string $subdomain The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateSubdomain($subdomain)
|
||||
{
|
||||
if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){
|
||||
if (!$this->_validateDliteral($arr[1])) return false;
|
||||
} else {
|
||||
if (!$this->_validateAtom($subdomain)) return false;
|
||||
}
|
||||
|
||||
// Got here, so return successful.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a domain literal:
|
||||
* domain-literal = "[" *(dtext / quoted-pair) "]"
|
||||
*
|
||||
* @access private
|
||||
* @param string $dliteral The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateDliteral($dliteral)
|
||||
{
|
||||
return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && $matches[1] != '\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate an addr-spec.
|
||||
*
|
||||
* addr-spec = local-part "@" domain
|
||||
*
|
||||
* @access private
|
||||
* @param string $addr_spec The string to check.
|
||||
* @return mixed False on failure, or the validated addr-spec on success.
|
||||
*/
|
||||
function _validateAddrSpec($addr_spec)
|
||||
{
|
||||
$addr_spec = trim($addr_spec);
|
||||
|
||||
// Split on @ sign if there is one.
|
||||
if (strpos($addr_spec, '@') !== false) {
|
||||
$parts = explode('@', $addr_spec);
|
||||
$local_part = $this->_splitCheck($parts, '@');
|
||||
$domain = substr($addr_spec, strlen($local_part . '@'));
|
||||
|
||||
// No @ sign so assume the default domain.
|
||||
} else {
|
||||
$local_part = $addr_spec;
|
||||
$domain = $this->default_domain;
|
||||
}
|
||||
|
||||
if (($local_part = $this->_validateLocalPart($local_part)) === false) return false;
|
||||
if (($domain = $this->_validateDomain($domain)) === false) return false;
|
||||
|
||||
// Got here so return successful.
|
||||
return array('local_part' => $local_part, 'domain' => $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate the local part of an address:
|
||||
* local-part = word *("." word)
|
||||
*
|
||||
* @access private
|
||||
* @param string $local_part
|
||||
* @return mixed False on failure, or the validated local part on success.
|
||||
*/
|
||||
function _validateLocalPart($local_part)
|
||||
{
|
||||
$parts = explode('.', $local_part);
|
||||
$words = array();
|
||||
|
||||
// Split the local_part into words.
|
||||
while (count($parts) > 0){
|
||||
$words[] = $this->_splitCheck($parts, '.');
|
||||
for ($i = 0; $i < $this->index + 1; $i++) {
|
||||
array_shift($parts);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate each word.
|
||||
foreach ($words as $word) {
|
||||
// If this word contains an unquoted space, it is invalid. (6.2.4)
|
||||
if (strpos($word, ' ') && $word[0] !== '"')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->_validatePhrase(trim($word)) === false) return false;
|
||||
}
|
||||
|
||||
// Managed to get here, so return the input.
|
||||
return $local_part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an approximate count of how many addresses are in the
|
||||
* given string. This is APPROXIMATE as it only splits based on a
|
||||
* comma which has no preceding backslash. Could be useful as
|
||||
* large amounts of addresses will end up producing *large*
|
||||
* structures when used with parseAddressList().
|
||||
*
|
||||
* @param string $data Addresses to count
|
||||
* @return int Approximate count
|
||||
*/
|
||||
function approximateCount($data)
|
||||
{
|
||||
return count(preg_split('/(?<!\\\\),/', $data));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a email validating function separate to the rest of the
|
||||
* class. It simply validates whether an email is of the common
|
||||
* internet form: <user>@<domain>. This can be sufficient for most
|
||||
* people. Optional stricter mode can be utilised which restricts
|
||||
* mailbox characters allowed to alphanumeric, full stop, hyphen
|
||||
* and underscore.
|
||||
*
|
||||
* @param string $data Address to check
|
||||
* @param boolean $strict Optional stricter mode
|
||||
* @return mixed False if it fails, an indexed array
|
||||
* username/domain if it matches
|
||||
*/
|
||||
function isValidInetAddress($data, $strict = false)
|
||||
{
|
||||
$regex = $strict ? '/^([.0-9a-z_-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i';
|
||||
if (preg_match($regex, trim($data), $matches)) {
|
||||
return array($matches[1], $matches[2]);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
|
||||
/**
|
||||
* internal PHP-mail() implementation of the PEAR Mail:: interface.
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail_mail extends Mail {
|
||||
|
||||
/**
|
||||
* Any arguments to pass to the mail() function.
|
||||
* @var string
|
||||
*/
|
||||
var $_params = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Instantiates a new Mail_mail:: object based on the parameters
|
||||
* passed in.
|
||||
*
|
||||
* @param array $params Extra arguments for the mail() function.
|
||||
*/
|
||||
function Mail_mail($params = null)
|
||||
{
|
||||
/* The other mail implementations accept parameters as arrays.
|
||||
* In the interest of being consistent, explode an array into
|
||||
* a string of parameter arguments. */
|
||||
if (is_array($params)) {
|
||||
$this->_params = join(' ', $params);
|
||||
} else {
|
||||
$this->_params = $params;
|
||||
}
|
||||
|
||||
/* Because the mail() function may pass headers as command
|
||||
* line arguments, we can't guarantee the use of the standard
|
||||
* "\r\n" separator. Instead, we use the system's native line
|
||||
* separator. */
|
||||
$this->sep = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Mail_mail::send() function using php's built-in mail()
|
||||
* command.
|
||||
*
|
||||
* @param mixed $recipients Either a comma-seperated list of recipients
|
||||
* (RFC822 compliant), or an array of recipients,
|
||||
* each RFC822 valid. This may contain recipients not
|
||||
* specified in the headers, for Bcc:, resending
|
||||
* messages, etc.
|
||||
*
|
||||
* @param array $headers The array of headers to send with the mail, in an
|
||||
* associative array, where the array key is the
|
||||
* header name (ie, 'Subject'), and the array value
|
||||
* is the header value (ie, 'test'). The header
|
||||
* produced from those values would be 'Subject:
|
||||
* test'.
|
||||
*
|
||||
* @param string $body The full text of the message body, including any
|
||||
* Mime parts, etc.
|
||||
*
|
||||
* @return mixed Returns true on success, or a PEAR_Error
|
||||
* containing a descriptive error message on
|
||||
* failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function send($recipients, $headers, $body)
|
||||
{
|
||||
// If we're passed an array of recipients, implode it.
|
||||
if (is_array($recipients)) {
|
||||
$recipients = implode(', ', $recipients);
|
||||
}
|
||||
|
||||
// Get the Subject out of the headers array so that we can
|
||||
// pass it as a seperate argument to mail().
|
||||
$subject = '';
|
||||
if (isset($headers['Subject'])) {
|
||||
$subject = $headers['Subject'];
|
||||
unset($headers['Subject']);
|
||||
}
|
||||
|
||||
// Flatten the headers out.
|
||||
$headerElements = $this->prepareHeaders($headers);
|
||||
if (PEAR::isError($headerElements)) {
|
||||
return $headerElements;
|
||||
}
|
||||
list(, $text_headers) = $headerElements;
|
||||
|
||||
/*
|
||||
* We only use mail()'s optional fifth parameter if the additional
|
||||
* parameters have been provided and we're not running in safe mode.
|
||||
*/
|
||||
if (empty($this->_params) || ini_get('safe_mode')) {
|
||||
$result = mail($recipients, $subject, $body, $text_headers);
|
||||
} else {
|
||||
$result = mail($recipients, $subject, $body, $text_headers,
|
||||
$this->_params);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the mail() function returned failure, we need to create a
|
||||
* PEAR_Error object and return it instead of the boolean result.
|
||||
*/
|
||||
if ($result === false) {
|
||||
$result = PEAR::raiseError('mail() returned failure');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,836 +0,0 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2002-2003 Richard Heyes |
|
||||
// | Copyright (c) 2003-2005 The PHP Group |
|
||||
// | All rights reserved. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | o Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | o Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution.|
|
||||
// | o The names of the authors may not be used to endorse or promote |
|
||||
// | products derived from this software without specific prior written |
|
||||
// | permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
||||
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
||||
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
||||
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
||||
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||
// | |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Author: Richard Heyes <richard@phpguru.org> |
|
||||
// +-----------------------------------------------------------------------+
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* +----------------------------- IMPORTANT ------------------------------+
|
||||
* | Usage of this class compared to native php extensions such as |
|
||||
* | mailparse or imap, is slow and may be feature deficient. If available|
|
||||
* | you are STRONGLY recommended to use the php extensions. |
|
||||
* +----------------------------------------------------------------------+
|
||||
*
|
||||
* Mime Decoding class
|
||||
*
|
||||
* This class will parse a raw mime email and return
|
||||
* the structure. Returned structure is similar to
|
||||
* that returned by imap_fetchstructure().
|
||||
*
|
||||
* USAGE: (assume $input is your raw email)
|
||||
*
|
||||
* $decode = new Mail_mimeDecode($input, "\r\n");
|
||||
* $structure = $decode->decode();
|
||||
* print_r($structure);
|
||||
*
|
||||
* Or statically:
|
||||
*
|
||||
* $params['input'] = $input;
|
||||
* $structure = Mail_mimeDecode::decode($params);
|
||||
* print_r($structure);
|
||||
*
|
||||
* TODO:
|
||||
* o Implement multipart/appledouble
|
||||
* o UTF8: ???
|
||||
|
||||
> 4. We have also found a solution for decoding the UTF-8
|
||||
> headers. Therefore I made the following function:
|
||||
>
|
||||
> function decode_utf8($txt) {
|
||||
> $trans=array("<22>‘"=>"õ","ű"=>"û","Ő"=>"<22>•","Ű"
|
||||
=>"<22>›");
|
||||
> $txt=strtr($txt,$trans);
|
||||
> return(utf8_decode($txt));
|
||||
> }
|
||||
>
|
||||
> And I have inserted the following line to the class:
|
||||
>
|
||||
> if (strtolower($charset)=="utf-8") $text=decode_utf8($text);
|
||||
>
|
||||
> ... before the following one in the "_decodeHeader" function:
|
||||
>
|
||||
> $input = str_replace($encoded, $text, $input);
|
||||
>
|
||||
> This way from now on it can easily decode the UTF-8 headers too.
|
||||
|
||||
*
|
||||
* @author Richard Heyes <richard@phpguru.org>
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail_mimeDecode extends PEAR
|
||||
{
|
||||
/**
|
||||
* The raw email to decode
|
||||
* @var string
|
||||
*/
|
||||
var $_input;
|
||||
|
||||
/**
|
||||
* The header part of the input
|
||||
* @var string
|
||||
*/
|
||||
var $_header;
|
||||
|
||||
/**
|
||||
* The body part of the input
|
||||
* @var string
|
||||
*/
|
||||
var $_body;
|
||||
|
||||
/**
|
||||
* If an error occurs, this is used to store the message
|
||||
* @var string
|
||||
*/
|
||||
var $_error;
|
||||
|
||||
/**
|
||||
* Flag to determine whether to include bodies in the
|
||||
* returned object.
|
||||
* @var boolean
|
||||
*/
|
||||
var $_include_bodies;
|
||||
|
||||
/**
|
||||
* Flag to determine whether to decode bodies
|
||||
* @var boolean
|
||||
*/
|
||||
var $_decode_bodies;
|
||||
|
||||
/**
|
||||
* Flag to determine whether to decode headers
|
||||
* @var boolean
|
||||
*/
|
||||
var $_decode_headers;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the object, initialise the variables, and splits and
|
||||
* stores the header and body of the input.
|
||||
*
|
||||
* @param string The input to decode
|
||||
* @access public
|
||||
*/
|
||||
function Mail_mimeDecode($input)
|
||||
{
|
||||
list($header, $body) = $this->_splitBodyHeader($input);
|
||||
|
||||
$this->_input = $input;
|
||||
$this->_header = $header;
|
||||
$this->_body = $body;
|
||||
$this->_decode_bodies = false;
|
||||
$this->_include_bodies = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins the decoding process. If called statically
|
||||
* it will create an object and call the decode() method
|
||||
* of it.
|
||||
*
|
||||
* @param array An array of various parameters that determine
|
||||
* various things:
|
||||
* include_bodies - Whether to include the body in the returned
|
||||
* object.
|
||||
* decode_bodies - Whether to decode the bodies
|
||||
* of the parts. (Transfer encoding)
|
||||
* decode_headers - Whether to decode headers
|
||||
* input - If called statically, this will be treated
|
||||
* as the input
|
||||
* @return object Decoded results
|
||||
* @access public
|
||||
*/
|
||||
function decode($params = null)
|
||||
{
|
||||
// determine if this method has been called statically
|
||||
$isStatic = !(isset($this) && get_class($this) == __CLASS__);
|
||||
|
||||
// Have we been called statically?
|
||||
// If so, create an object and pass details to that.
|
||||
if ($isStatic AND isset($params['input'])) {
|
||||
|
||||
$obj = new Mail_mimeDecode($params['input']);
|
||||
$structure = $obj->decode($params);
|
||||
|
||||
// Called statically but no input
|
||||
} elseif ($isStatic) {
|
||||
return PEAR::raiseError('Called statically and no input given');
|
||||
|
||||
// Called via an object
|
||||
} else {
|
||||
$this->_include_bodies = isset($params['include_bodies']) ?
|
||||
$params['include_bodies'] : false;
|
||||
$this->_decode_bodies = isset($params['decode_bodies']) ?
|
||||
$params['decode_bodies'] : false;
|
||||
$this->_decode_headers = isset($params['decode_headers']) ?
|
||||
$params['decode_headers'] : false;
|
||||
|
||||
$structure = $this->_decode($this->_header, $this->_body);
|
||||
if ($structure === false) {
|
||||
$structure = $this->raiseError($this->_error);
|
||||
}
|
||||
}
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the decoding. Decodes the body string passed to it
|
||||
* If it finds certain content-types it will call itself in a
|
||||
* recursive fashion
|
||||
*
|
||||
* @param string Header section
|
||||
* @param string Body section
|
||||
* @return object Results of decoding process
|
||||
* @access private
|
||||
*/
|
||||
function _decode($headers, $body, $default_ctype = 'text/plain')
|
||||
{
|
||||
$return = new stdClass;
|
||||
$return->headers = array();
|
||||
$headers = $this->_parseHeaders($headers);
|
||||
|
||||
foreach ($headers as $value) {
|
||||
if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {
|
||||
$return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]);
|
||||
$return->headers[strtolower($value['name'])][] = $value['value'];
|
||||
|
||||
} elseif (isset($return->headers[strtolower($value['name'])])) {
|
||||
$return->headers[strtolower($value['name'])][] = $value['value'];
|
||||
|
||||
} else {
|
||||
$return->headers[strtolower($value['name'])] = $value['value'];
|
||||
}
|
||||
}
|
||||
|
||||
reset($headers);
|
||||
while (list($key, $value) = each($headers)) {
|
||||
$headers[$key]['name'] = strtolower($headers[$key]['name']);
|
||||
switch ($headers[$key]['name']) {
|
||||
|
||||
case 'content-type':
|
||||
$content_type = $this->_parseHeaderValue($headers[$key]['value']);
|
||||
|
||||
if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) {
|
||||
$return->ctype_primary = $regs[1];
|
||||
$return->ctype_secondary = $regs[2];
|
||||
}
|
||||
|
||||
if (isset($content_type['other'])) {
|
||||
while (list($p_name, $p_value) = each($content_type['other'])) {
|
||||
$return->ctype_parameters[$p_name] = $p_value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'content-disposition':
|
||||
$content_disposition = $this->_parseHeaderValue($headers[$key]['value']);
|
||||
$return->disposition = $content_disposition['value'];
|
||||
if (isset($content_disposition['other'])) {
|
||||
while (list($p_name, $p_value) = each($content_disposition['other'])) {
|
||||
$return->d_parameters[$p_name] = $p_value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'content-transfer-encoding':
|
||||
$content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($content_type)) {
|
||||
switch (strtolower($content_type['value'])) {
|
||||
case 'text/plain':
|
||||
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
|
||||
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
|
||||
break;
|
||||
|
||||
case 'text/html':
|
||||
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
|
||||
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
|
||||
break;
|
||||
|
||||
case 'multipart/parallel':
|
||||
case 'multipart/report': // RFC1892
|
||||
case 'multipart/signed': // PGP
|
||||
case 'multipart/digest':
|
||||
case 'multipart/alternative':
|
||||
case 'multipart/related':
|
||||
case 'multipart/mixed':
|
||||
if(!isset($content_type['other']['boundary'])){
|
||||
$this->_error = 'No boundary found for ' . $content_type['value'] . ' part';
|
||||
return false;
|
||||
}
|
||||
|
||||
$default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain';
|
||||
|
||||
$parts = $this->_boundarySplit($body, $content_type['other']['boundary']);
|
||||
for ($i = 0; $i < count($parts); $i++) {
|
||||
list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]);
|
||||
$part = $this->_decode($part_header, $part_body, $default_ctype);
|
||||
if($part === false)
|
||||
$part = $this->raiseError($this->_error);
|
||||
$return->parts[] = $part;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'message/rfc822':
|
||||
$obj = new Mail_mimeDecode($body);
|
||||
$return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies,
|
||||
'decode_bodies' => $this->_decode_bodies,
|
||||
'decode_headers' => $this->_decode_headers));
|
||||
unset($obj);
|
||||
break;
|
||||
|
||||
default:
|
||||
if(!isset($content_transfer_encoding['value']))
|
||||
$content_transfer_encoding['value'] = '7bit';
|
||||
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null;
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
$ctype = explode('/', $default_ctype);
|
||||
$return->ctype_primary = $ctype[0];
|
||||
$return->ctype_secondary = $ctype[1];
|
||||
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the output of the above function, this will return an
|
||||
* array of references to the parts, indexed by mime number.
|
||||
*
|
||||
* @param object $structure The structure to go through
|
||||
* @param string $mime_number Internal use only.
|
||||
* @return array Mime numbers
|
||||
*/
|
||||
function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '')
|
||||
{
|
||||
$return = array();
|
||||
if (!empty($structure->parts)) {
|
||||
if ($mime_number != '') {
|
||||
$structure->mime_id = $prepend . $mime_number;
|
||||
$return[$prepend . $mime_number] = &$structure;
|
||||
}
|
||||
for ($i = 0; $i < count($structure->parts); $i++) {
|
||||
|
||||
|
||||
if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') {
|
||||
$prepend = $prepend . $mime_number . '.';
|
||||
$_mime_number = '';
|
||||
} else {
|
||||
$_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1));
|
||||
}
|
||||
|
||||
$arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend);
|
||||
foreach ($arr as $key => $val) {
|
||||
$no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($mime_number == '') {
|
||||
$mime_number = '1';
|
||||
}
|
||||
$structure->mime_id = $prepend . $mime_number;
|
||||
$no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string containing a header and body
|
||||
* section, this function will split them (at the first
|
||||
* blank line) and return them.
|
||||
*
|
||||
* @param string Input to split apart
|
||||
* @return array Contains header and body section
|
||||
* @access private
|
||||
*/
|
||||
function _splitBodyHeader($input)
|
||||
{
|
||||
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
|
||||
return array($match[1], $match[2]);
|
||||
}
|
||||
$this->_error = 'Could not split header and body';
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse headers given in $input and return
|
||||
* as assoc array.
|
||||
*
|
||||
* @param string Headers to parse
|
||||
* @return array Contains parsed headers
|
||||
* @access private
|
||||
*/
|
||||
function _parseHeaders($input)
|
||||
{
|
||||
|
||||
if ($input !== '') {
|
||||
// Unfold the input
|
||||
$input = preg_replace("/\r?\n/", "\r\n", $input);
|
||||
$input = preg_replace("/\r\n(\t| )+/", ' ', $input);
|
||||
$headers = explode("\r\n", trim($input));
|
||||
|
||||
foreach ($headers as $value) {
|
||||
$hdr_name = substr($value, 0, $pos = strpos($value, ':'));
|
||||
$hdr_value = substr($value, $pos+1);
|
||||
if($hdr_value[0] == ' ')
|
||||
$hdr_value = substr($hdr_value, 1);
|
||||
|
||||
$return[] = array(
|
||||
'name' => $hdr_name,
|
||||
'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$return = array();
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to parse a header value,
|
||||
* extract first part, and any secondary
|
||||
* parts (after ;) This function is not as
|
||||
* robust as it could be. Eg. header comments
|
||||
* in the wrong place will probably break it.
|
||||
*
|
||||
* @param string Header value to parse
|
||||
* @return array Contains parsed result
|
||||
* @access private
|
||||
*/
|
||||
function _parseHeaderValue($input)
|
||||
{
|
||||
|
||||
if (($pos = strpos($input, ';')) !== false) {
|
||||
|
||||
$return['value'] = trim(substr($input, 0, $pos));
|
||||
$input = trim(substr($input, $pos+1));
|
||||
|
||||
if (strlen($input) > 0) {
|
||||
|
||||
// This splits on a semi-colon, if there's no preceeding backslash
|
||||
// Now works with quoted values; had to glue the \; breaks in PHP
|
||||
// the regex is already bordering on incomprehensible
|
||||
$splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/';
|
||||
preg_match_all($splitRegex, $input, $matches);
|
||||
$parameters = array();
|
||||
for ($i=0; $i<count($matches[0]); $i++) {
|
||||
$param = $matches[0][$i];
|
||||
while (substr($param, -2) == '\;') {
|
||||
$param .= $matches[0][++$i];
|
||||
}
|
||||
$parameters[] = $param;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($parameters); $i++) {
|
||||
$param_name = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ ");
|
||||
$param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ ");
|
||||
if ($param_value[0] == '"') {
|
||||
$param_value = substr($param_value, 1, -1);
|
||||
}
|
||||
$return['other'][$param_name] = $param_value;
|
||||
$return['other'][strtolower($param_name)] = $param_value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$return['value'] = trim($input);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function splits the input based
|
||||
* on the given boundary
|
||||
*
|
||||
* @param string Input to parse
|
||||
* @return array Contains array of resulting mime parts
|
||||
* @access private
|
||||
*/
|
||||
function _boundarySplit($input, $boundary)
|
||||
{
|
||||
$parts = array();
|
||||
|
||||
$bs_possible = substr($boundary, 2, -2);
|
||||
$bs_check = '\"' . $bs_possible . '\"';
|
||||
|
||||
if ($boundary == $bs_check) {
|
||||
$boundary = $bs_possible;
|
||||
}
|
||||
|
||||
$tmp = explode('--' . $boundary, $input);
|
||||
|
||||
for ($i = 1; $i < count($tmp) - 1; $i++) {
|
||||
$parts[] = $tmp[$i];
|
||||
}
|
||||
|
||||
return $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a header, this function will decode it
|
||||
* according to RFC2047. Probably not *exactly*
|
||||
* conformant, but it does pass all the given
|
||||
* examples (in RFC2047).
|
||||
*
|
||||
* @param string Input header value to decode
|
||||
* @return string Decoded header value
|
||||
* @access private
|
||||
*/
|
||||
function _decodeHeader($input)
|
||||
{
|
||||
// Remove white space between encoded-words
|
||||
$input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
|
||||
|
||||
// For each encoded-word...
|
||||
while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
|
||||
|
||||
$encoded = $matches[1];
|
||||
$charset = $matches[2];
|
||||
$encoding = $matches[3];
|
||||
$text = $matches[4];
|
||||
|
||||
switch (strtolower($encoding)) {
|
||||
case 'b':
|
||||
$text = base64_decode($text);
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
$text = str_replace('_', ' ', $text);
|
||||
preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
|
||||
foreach($matches[1] as $value)
|
||||
$text = str_replace('='.$value, chr(hexdec($value)), $text);
|
||||
break;
|
||||
}
|
||||
|
||||
$input = str_replace($encoded, $text, $input);
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a body string and an encoding type,
|
||||
* this function will decode and return it.
|
||||
*
|
||||
* @param string Input body to decode
|
||||
* @param string Encoding type to use.
|
||||
* @return string Decoded body
|
||||
* @access private
|
||||
*/
|
||||
function _decodeBody($input, $encoding = '7bit')
|
||||
{
|
||||
switch (strtolower($encoding)) {
|
||||
case '7bit':
|
||||
return $input;
|
||||
break;
|
||||
|
||||
case 'quoted-printable':
|
||||
return $this->_quotedPrintableDecode($input);
|
||||
break;
|
||||
|
||||
case 'base64':
|
||||
return base64_decode($input);
|
||||
break;
|
||||
|
||||
default:
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a quoted-printable string, this
|
||||
* function will decode and return it.
|
||||
*
|
||||
* @param string Input body to decode
|
||||
* @return string Decoded body
|
||||
* @access private
|
||||
*/
|
||||
function _quotedPrintableDecode($input)
|
||||
{
|
||||
// Remove soft line breaks
|
||||
$input = preg_replace("/=\r?\n/", '', $input);
|
||||
|
||||
// Replace encoded characters
|
||||
$input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input);
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the input for uuencoded files and returns
|
||||
* an array of them. Can be called statically, eg:
|
||||
*
|
||||
* $files =& Mail_mimeDecode::uudecode($some_text);
|
||||
*
|
||||
* It will check for the begin 666 ... end syntax
|
||||
* however and won't just blindly decode whatever you
|
||||
* pass it.
|
||||
*
|
||||
* @param string Input body to look for attahcments in
|
||||
* @return array Decoded bodies, filenames and permissions
|
||||
* @access public
|
||||
* @author Unknown
|
||||
*/
|
||||
function &uudecode($input)
|
||||
{
|
||||
// Find all uuencoded sections
|
||||
preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches);
|
||||
|
||||
for ($j = 0; $j < count($matches[3]); $j++) {
|
||||
|
||||
$str = $matches[3][$j];
|
||||
$filename = $matches[2][$j];
|
||||
$fileperm = $matches[1][$j];
|
||||
|
||||
$file = '';
|
||||
$str = preg_split("/\r?\n/", trim($str));
|
||||
$strlen = count($str);
|
||||
|
||||
for ($i = 0; $i < $strlen; $i++) {
|
||||
$pos = 1;
|
||||
$d = 0;
|
||||
$len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077);
|
||||
|
||||
while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) {
|
||||
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
|
||||
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
|
||||
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
|
||||
$c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20);
|
||||
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
|
||||
|
||||
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
|
||||
|
||||
$file .= chr(((($c2 - ' ') & 077) << 6) | (($c3 - ' ') & 077));
|
||||
|
||||
$pos += 4;
|
||||
$d += 3;
|
||||
}
|
||||
|
||||
if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) {
|
||||
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
|
||||
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
|
||||
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
|
||||
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
|
||||
|
||||
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
|
||||
|
||||
$pos += 3;
|
||||
$d += 2;
|
||||
}
|
||||
|
||||
if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) {
|
||||
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
|
||||
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
|
||||
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
|
||||
|
||||
}
|
||||
}
|
||||
$files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* getSendArray() returns the arguments required for Mail::send()
|
||||
* used to build the arguments for a mail::send() call
|
||||
*
|
||||
* Usage:
|
||||
* $mailtext = Full email (for example generated by a template)
|
||||
* $decoder = new Mail_mimeDecode($mailtext);
|
||||
* $parts = $decoder->getSendArray();
|
||||
* if (!PEAR::isError($parts) {
|
||||
* list($recipents,$headers,$body) = $parts;
|
||||
* $mail = Mail::factory('smtp');
|
||||
* $mail->send($recipents,$headers,$body);
|
||||
* } else {
|
||||
* echo $parts->message;
|
||||
* }
|
||||
* @return mixed array of recipeint, headers,body or Pear_Error
|
||||
* @access public
|
||||
* @author Alan Knowles <alan@akbkhome.com>
|
||||
*/
|
||||
function getSendArray()
|
||||
{
|
||||
// prevent warning if this is not set
|
||||
$this->_decode_headers = FALSE;
|
||||
$headerlist =$this->_parseHeaders($this->_header);
|
||||
$to = "";
|
||||
if (!$headerlist) {
|
||||
return $this->raiseError("Message did not contain headers");
|
||||
}
|
||||
foreach($headerlist as $item) {
|
||||
$header[$item['name']] = $item['value'];
|
||||
switch (strtolower($item['name'])) {
|
||||
case "to":
|
||||
case "cc":
|
||||
case "bcc":
|
||||
$to = ",".$item['value'];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($to == "") {
|
||||
return $this->raiseError("Message did not contain any recipents");
|
||||
}
|
||||
$to = substr($to,1);
|
||||
return array($to,$header,$this->_body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a xml copy of the output of
|
||||
* Mail_mimeDecode::decode. Pass the output in as the
|
||||
* argument. This function can be called statically. Eg:
|
||||
*
|
||||
* $output = $obj->decode();
|
||||
* $xml = Mail_mimeDecode::getXML($output);
|
||||
*
|
||||
* The DTD used for this should have been in the package. Or
|
||||
* alternatively you can get it from cvs, or here:
|
||||
* http://www.phpguru.org/xmail/xmail.dtd.
|
||||
*
|
||||
* @param object Input to convert to xml. This should be the
|
||||
* output of the Mail_mimeDecode::decode function
|
||||
* @return string XML version of input
|
||||
* @access public
|
||||
*/
|
||||
function getXML($input)
|
||||
{
|
||||
$crlf = "\r\n";
|
||||
$output = '<?xml version=\'1.0\'?>' . $crlf .
|
||||
'<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf .
|
||||
'<email>' . $crlf .
|
||||
Mail_mimeDecode::_getXML($input) .
|
||||
'</email>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that does the actual conversion to xml. Does a single
|
||||
* mimepart at a time.
|
||||
*
|
||||
* @param object Input to convert to xml. This is a mimepart object.
|
||||
* It may or may not contain subparts.
|
||||
* @param integer Number of tabs to indent
|
||||
* @return string XML version of input
|
||||
* @access private
|
||||
*/
|
||||
function _getXML($input, $indent = 1)
|
||||
{
|
||||
$htab = "\t";
|
||||
$crlf = "\r\n";
|
||||
$output = '';
|
||||
$headers = @(array)$input->headers;
|
||||
|
||||
foreach ($headers as $hdr_name => $hdr_value) {
|
||||
|
||||
// Multiple headers with this name
|
||||
if (is_array($headers[$hdr_name])) {
|
||||
for ($i = 0; $i < count($hdr_value); $i++) {
|
||||
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent);
|
||||
}
|
||||
|
||||
// Only one header of this sort
|
||||
} else {
|
||||
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($input->parts)) {
|
||||
for ($i = 0; $i < count($input->parts); $i++) {
|
||||
$output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf .
|
||||
Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) .
|
||||
str_repeat($htab, $indent) . '</mimepart>' . $crlf;
|
||||
}
|
||||
} elseif (isset($input->body)) {
|
||||
$output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' .
|
||||
$input->body . ']]></body>' . $crlf;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to _getXML(). Returns xml of a header.
|
||||
*
|
||||
* @param string Name of header
|
||||
* @param string Value of header
|
||||
* @param integer Number of tabs to indent
|
||||
* @return string XML version of input
|
||||
* @access private
|
||||
*/
|
||||
function _getXML_helper($hdr_name, $hdr_value, $indent)
|
||||
{
|
||||
$htab = "\t";
|
||||
$crlf = "\r\n";
|
||||
$return = '';
|
||||
|
||||
$new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value);
|
||||
$new_hdr_name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name)));
|
||||
|
||||
// Sort out any parameters
|
||||
if (!empty($new_hdr_value['other'])) {
|
||||
foreach ($new_hdr_value['other'] as $paramname => $paramvalue) {
|
||||
$params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf .
|
||||
str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf .
|
||||
str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf .
|
||||
str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf;
|
||||
}
|
||||
|
||||
$params = implode('', $params);
|
||||
} else {
|
||||
$params = '';
|
||||
}
|
||||
|
||||
$return = str_repeat($htab, $indent) . '<header>' . $crlf .
|
||||
str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf .
|
||||
str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf .
|
||||
$params .
|
||||
str_repeat($htab, $indent) . '</header>' . $crlf;
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
} // End of class
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Phil Kernick <philk@rotfl.com.au> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
|
||||
/**
|
||||
* Null implementation of the PEAR Mail:: interface.
|
||||
* @access public
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail_null extends Mail {
|
||||
|
||||
/**
|
||||
* Implements Mail_null::send() function. Silently discards all
|
||||
* mail.
|
||||
*
|
||||
* @param mixed $recipients Either a comma-seperated list of recipients
|
||||
* (RFC822 compliant), or an array of recipients,
|
||||
* each RFC822 valid. This may contain recipients not
|
||||
* specified in the headers, for Bcc:, resending
|
||||
* messages, etc.
|
||||
*
|
||||
* @param array $headers The array of headers to send with the mail, in an
|
||||
* associative array, where the array key is the
|
||||
* header name (ie, 'Subject'), and the array value
|
||||
* is the header value (ie, 'test'). The header
|
||||
* produced from those values would be 'Subject:
|
||||
* test'.
|
||||
*
|
||||
* @param string $body The full text of the message body, including any
|
||||
* Mime parts, etc.
|
||||
*
|
||||
* @return mixed Returns true on success, or a PEAR_Error
|
||||
* containing a descriptive error message on
|
||||
* failure.
|
||||
* @access public
|
||||
*/
|
||||
function send($recipients, $headers, $body)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Sendmail implementation of the PEAR Mail:: interface.
|
||||
* @access public
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail_sendmail extends Mail {
|
||||
|
||||
/**
|
||||
* The location of the sendmail or sendmail wrapper binary on the
|
||||
* filesystem.
|
||||
* @var string
|
||||
*/
|
||||
var $sendmail_path = '/usr/sbin/sendmail';
|
||||
|
||||
/**
|
||||
* Any extra command-line parameters to pass to the sendmail or
|
||||
* sendmail wrapper binary.
|
||||
* @var string
|
||||
*/
|
||||
var $sendmail_args = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Instantiates a new Mail_sendmail:: object based on the parameters
|
||||
* passed in. It looks for the following parameters:
|
||||
* sendmail_path The location of the sendmail binary on the
|
||||
* filesystem. Defaults to '/usr/sbin/sendmail'.
|
||||
*
|
||||
* sendmail_args Any extra parameters to pass to the sendmail
|
||||
* or sendmail wrapper binary.
|
||||
*
|
||||
* If a parameter is present in the $params array, it replaces the
|
||||
* default.
|
||||
*
|
||||
* @param array $params Hash containing any parameters different from the
|
||||
* defaults.
|
||||
* @access public
|
||||
*/
|
||||
function Mail_sendmail($params)
|
||||
{
|
||||
if (isset($params['sendmail_path'])) $this->sendmail_path = $params['sendmail_path'];
|
||||
if (isset($params['sendmail_args'])) $this->sendmail_args = $params['sendmail_args'];
|
||||
|
||||
/*
|
||||
* Because we need to pass message headers to the sendmail program on
|
||||
* the commandline, we can't guarantee the use of the standard "\r\n"
|
||||
* separator. Instead, we use the system's native line separator.
|
||||
*/
|
||||
$this->sep = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Mail::send() function using the sendmail
|
||||
* command-line binary.
|
||||
*
|
||||
* @param mixed $recipients Either a comma-seperated list of recipients
|
||||
* (RFC822 compliant), or an array of recipients,
|
||||
* each RFC822 valid. This may contain recipients not
|
||||
* specified in the headers, for Bcc:, resending
|
||||
* messages, etc.
|
||||
*
|
||||
* @param array $headers The array of headers to send with the mail, in an
|
||||
* associative array, where the array key is the
|
||||
* header name (ie, 'Subject'), and the array value
|
||||
* is the header value (ie, 'test'). The header
|
||||
* produced from those values would be 'Subject:
|
||||
* test'.
|
||||
*
|
||||
* @param string $body The full text of the message body, including any
|
||||
* Mime parts, etc.
|
||||
*
|
||||
* @return mixed Returns true on success, or a PEAR_Error
|
||||
* containing a descriptive error message on
|
||||
* failure.
|
||||
* @access public
|
||||
*/
|
||||
function send($recipients, $headers, $body)
|
||||
{
|
||||
$recipients = $this->parseRecipients($recipients);
|
||||
if (PEAR::isError($recipients)) {
|
||||
return $recipients;
|
||||
}
|
||||
$recipients = escapeShellCmd(implode(' ', $recipients));
|
||||
|
||||
$headerElements = $this->prepareHeaders($headers);
|
||||
if (PEAR::isError($headerElements)) {
|
||||
return $headerElements;
|
||||
}
|
||||
list($from, $text_headers) = $headerElements;
|
||||
|
||||
if (!isset($from)) {
|
||||
return PEAR::raiseError('No from address given.');
|
||||
} elseif (strstr($from, ' ') ||
|
||||
strstr($from, ';') ||
|
||||
strstr($from, '&') ||
|
||||
strstr($from, '`')) {
|
||||
return PEAR::raiseError('From address specified with dangerous characters.');
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
if (@is_file($this->sendmail_path)) {
|
||||
$from = escapeShellCmd($from);
|
||||
$mail = popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w');
|
||||
fputs($mail, $text_headers);
|
||||
fputs($mail, $this->sep); // newline to end the headers section
|
||||
fputs($mail, $body);
|
||||
$result = pclose($mail);
|
||||
if (version_compare(phpversion(), '4.2.3') == -1) {
|
||||
// With older php versions, we need to shift the
|
||||
// pclose result to get the exit code.
|
||||
$result = $result >> 8 & 0xFF;
|
||||
}
|
||||
} else {
|
||||
return PEAR::raiseError('sendmail [' . $this->sendmail_path . '] is not a valid file');
|
||||
}
|
||||
|
||||
if ($result != 0) {
|
||||
return PEAR::raiseError('sendmail returned error code ' . $result,
|
||||
$result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// | Jon Parise <jon@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* SMTP implementation of the PEAR Mail:: interface. Requires the PEAR
|
||||
* Net_SMTP:: class.
|
||||
* @access public
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail_smtp extends Mail {
|
||||
|
||||
/**
|
||||
* The SMTP host to connect to.
|
||||
* @var string
|
||||
*/
|
||||
var $host = 'localhost';
|
||||
|
||||
/**
|
||||
* The port the SMTP server is on.
|
||||
* @var integer
|
||||
*/
|
||||
var $port = 25;
|
||||
|
||||
/**
|
||||
* Should SMTP authentication be used?
|
||||
*
|
||||
* This value may be set to true, false or the name of a specific
|
||||
* authentication method.
|
||||
*
|
||||
* If the value is set to true, the Net_SMTP package will attempt to use
|
||||
* the best authentication method advertised by the remote SMTP server.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
var $auth = false;
|
||||
|
||||
/**
|
||||
* The username to use if the SMTP server requires authentication.
|
||||
* @var string
|
||||
*/
|
||||
var $username = '';
|
||||
|
||||
/**
|
||||
* The password to use if the SMTP server requires authentication.
|
||||
* @var string
|
||||
*/
|
||||
var $password = '';
|
||||
|
||||
/**
|
||||
* Hostname or domain that will be sent to the remote SMTP server in the
|
||||
* HELO / EHLO message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $localhost = 'localhost';
|
||||
|
||||
/**
|
||||
* SMTP connection timeout value. NULL indicates no timeout.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $timeout = null;
|
||||
|
||||
/**
|
||||
* Whether to use VERP or not. If not a boolean, the string value
|
||||
* will be used as the VERP separators.
|
||||
*
|
||||
* @var mixed boolean or string
|
||||
*/
|
||||
var $verp = false;
|
||||
|
||||
/**
|
||||
* Turn on Net_SMTP debugging?
|
||||
*
|
||||
* @var boolean $debug
|
||||
*/
|
||||
var $debug = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Instantiates a new Mail_smtp:: object based on the parameters
|
||||
* passed in. It looks for the following parameters:
|
||||
* host The server to connect to. Defaults to localhost.
|
||||
* port The port to connect to. Defaults to 25.
|
||||
* auth SMTP authentication. Defaults to none.
|
||||
* username The username to use for SMTP auth. No default.
|
||||
* password The password to use for SMTP auth. No default.
|
||||
* localhost The local hostname / domain. Defaults to localhost.
|
||||
* timeout The SMTP connection timeout. Defaults to none.
|
||||
* verp Whether to use VERP or not. Defaults to false.
|
||||
* debug Activate SMTP debug mode? Defaults to false.
|
||||
*
|
||||
* If a parameter is present in the $params array, it replaces the
|
||||
* default.
|
||||
*
|
||||
* @param array Hash containing any parameters different from the
|
||||
* defaults.
|
||||
* @access public
|
||||
*/
|
||||
function Mail_smtp($params)
|
||||
{
|
||||
if (isset($params['host'])) $this->host = $params['host'];
|
||||
if (isset($params['port'])) $this->port = $params['port'];
|
||||
if (isset($params['auth'])) $this->auth = $params['auth'];
|
||||
if (isset($params['username'])) $this->username = $params['username'];
|
||||
if (isset($params['password'])) $this->password = $params['password'];
|
||||
if (isset($params['localhost'])) $this->localhost = $params['localhost'];
|
||||
if (isset($params['timeout'])) $this->timeout = $params['timeout'];
|
||||
if (isset($params['verp'])) $this->verp = $params['verp'];
|
||||
if (isset($params['debug'])) $this->debug = (boolean)$params['debug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Mail::send() function using SMTP.
|
||||
*
|
||||
* @param mixed $recipients Either a comma-seperated list of recipients
|
||||
* (RFC822 compliant), or an array of recipients,
|
||||
* each RFC822 valid. This may contain recipients not
|
||||
* specified in the headers, for Bcc:, resending
|
||||
* messages, etc.
|
||||
*
|
||||
* @param array $headers The array of headers to send with the mail, in an
|
||||
* associative array, where the array key is the
|
||||
* header name (e.g., 'Subject'), and the array value
|
||||
* is the header value (e.g., 'test'). The header
|
||||
* produced from those values would be 'Subject:
|
||||
* test'.
|
||||
*
|
||||
* @param string $body The full text of the message body, including any
|
||||
* Mime parts, etc.
|
||||
*
|
||||
* @return mixed Returns true on success, or a PEAR_Error
|
||||
* containing a descriptive error message on
|
||||
* failure.
|
||||
* @access public
|
||||
*/
|
||||
function send($recipients, $headers, $body)
|
||||
{
|
||||
include_once 'Net/SMTP.php';
|
||||
|
||||
if (!($smtp = &new Net_SMTP($this->host, $this->port, $this->localhost))) {
|
||||
return PEAR::raiseError('unable to instantiate Net_SMTP object');
|
||||
}
|
||||
|
||||
if ($this->debug) {
|
||||
$smtp->setDebug(true);
|
||||
}
|
||||
|
||||
if (PEAR::isError($smtp->connect($this->timeout))) {
|
||||
return PEAR::raiseError('unable to connect to smtp server ' .
|
||||
$this->host . ':' . $this->port);
|
||||
}
|
||||
|
||||
if ($this->auth) {
|
||||
$method = is_string($this->auth) ? $this->auth : '';
|
||||
|
||||
if (PEAR::isError($smtp->auth($this->username, $this->password,
|
||||
$method))) {
|
||||
return PEAR::raiseError('unable to authenticate to smtp server');
|
||||
}
|
||||
}
|
||||
|
||||
$headerElements = $this->prepareHeaders($headers);
|
||||
if (PEAR::isError($headerElements)) {
|
||||
return $headerElements;
|
||||
}
|
||||
list($from, $text_headers) = $headerElements;
|
||||
|
||||
/* Since few MTAs are going to allow this header to be forged
|
||||
* unless it's in the MAIL FROM: exchange, we'll use
|
||||
* Return-Path instead of From: if it's set. */
|
||||
if (!empty($headers['Return-Path'])) {
|
||||
$from = $headers['Return-Path'];
|
||||
}
|
||||
|
||||
if (!isset($from)) {
|
||||
return PEAR::raiseError('No from address given');
|
||||
}
|
||||
|
||||
$args['verp'] = $this->verp;
|
||||
if (PEAR::isError($smtp->mailFrom($from, $args))) {
|
||||
return PEAR::raiseError('unable to set sender to [' . $from . ']');
|
||||
}
|
||||
|
||||
$recipients = $this->parseRecipients($recipients);
|
||||
if (PEAR::isError($recipients)) {
|
||||
return $recipients;
|
||||
}
|
||||
|
||||
foreach ($recipients as $recipient) {
|
||||
if (PEAR::isError($res = $smtp->rcptTo($recipient))) {
|
||||
return PEAR::raiseError('unable to add recipient [' .
|
||||
$recipient . ']: ' . $res->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (PEAR::isError($smtp->data($text_headers . "\r\n" . $body))) {
|
||||
return PEAR::raiseError('unable to send data');
|
||||
}
|
||||
|
||||
$smtp->disconnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!ENTITY lt "&#60;">
|
||||
<!ENTITY gt ">">
|
||||
<!ENTITY amp "&#38;">
|
||||
<!ENTITY apos "'">
|
||||
<!ENTITY quot """>
|
||||
<!ENTITY crlf " ">
|
||||
|
||||
<!ELEMENT email (header+, (body | mimepart+))>
|
||||
<!ELEMENT mimepart (header+, (body | mimepart+))>
|
||||
<!ELEMENT body (#PCDATA)>
|
||||
<!ELEMENT header ((headername|headervalue|parameter)*)>
|
||||
<!ELEMENT headername (#PCDATA)>
|
||||
<!ELEMENT headervalue (#PCDATA)>
|
||||
<!ELEMENT parameter ((paramname|paramvalue)+)>
|
||||
<!ELEMENT paramvalue (#PCDATA)>
|
||||
<!ELEMENT paramname (#PCDATA)>
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
|
||||
<xsl:preserve-space elements="headervalue paramvalue body"/>
|
||||
|
||||
<xsl:template name="mimepart">
|
||||
|
||||
<xsl:variable name="boundary">
|
||||
<xsl:for-each select="./header">
|
||||
<xsl:if test="string(./headername) = 'Content-Type'">
|
||||
<xsl:for-each select="./parameter">
|
||||
<xsl:if test="string(./paramname) = 'boundary'">
|
||||
<xsl:value-of select="paramvalue"/>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:for-each select="header">
|
||||
|
||||
<xsl:value-of select="headername"/>
|
||||
<xsl:text>: </xsl:text>
|
||||
<xsl:value-of select="headervalue"/>
|
||||
|
||||
<xsl:if test="count(./parameter) = 0">
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:for-each select="parameter">
|
||||
<xsl:text>; 	</xsl:text>
|
||||
<xsl:value-of select="paramname"/>
|
||||
<xsl:text>="</xsl:text>
|
||||
<xsl:value-of select="paramvalue"/>
|
||||
<xsl:text>"</xsl:text>
|
||||
</xsl:for-each>
|
||||
|
||||
<xsl:if test="count(./parameter) > 0">
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:if>
|
||||
|
||||
</xsl:for-each>
|
||||
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<!-- Which to do, print a body or process subparts? -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="count(./mimepart) = 0">
|
||||
<xsl:value-of select="body"/>
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<xsl:for-each select="mimepart">
|
||||
<xsl:text>--</xsl:text><xsl:value-of select="$boundary"/><xsl:text> </xsl:text>
|
||||
<xsl:call-template name="mimepart"/>
|
||||
</xsl:for-each>
|
||||
|
||||
<xsl:text>--</xsl:text><xsl:value-of select="$boundary"/><xsl:text>-- </xsl:text>
|
||||
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- This is where the stylesheet really starts, matching the top level email element -->
|
||||
<xsl:template match="email">
|
||||
<xsl:call-template name="mimepart"/>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
@@ -394,7 +394,7 @@ if ($action == 'create')
|
||||
*/
|
||||
print '<td align="center">';
|
||||
$quantite_livree = $commande->livraisons[$line->id];
|
||||
print $quantite_livree;;
|
||||
print $quantite_livree;
|
||||
print '</td>';
|
||||
|
||||
$quantite_commandee = $line->qty;
|
||||
|
||||
@@ -367,7 +367,7 @@ if ($comments) {
|
||||
}
|
||||
else
|
||||
{
|
||||
print $langs->trans("NoCommentYet").'<br>';;
|
||||
print $langs->trans("NoCommentYet").'<br>';
|
||||
}
|
||||
|
||||
print '<br>';
|
||||
|
||||
@@ -268,7 +268,7 @@ if ($id > 0 || ! empty($ref))
|
||||
$productstatic->type=$value["fk_product_type"];
|
||||
$productstatic->ref=$value['label'];
|
||||
print '<tr>';
|
||||
print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';;
|
||||
print '<td>'.$productstatic->getNomUrl(1,'composition').'</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
print '</table>';
|
||||
|
||||
@@ -31,7 +31,7 @@ $langs->load("stocks");
|
||||
// Security check
|
||||
$result=restrictedArea($user,'stock');
|
||||
|
||||
$sref=GETPOST("sref");;
|
||||
$sref=GETPOST("sref");
|
||||
$snom=GETPOST("snom");
|
||||
$sall=GETPOST("sall");
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ if ($id > 0 || ! empty($ref))
|
||||
$colwidth=30;
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php';
|
||||
|
||||
dol_fiche_end();;
|
||||
dol_fiche_end();
|
||||
}
|
||||
|
||||
llxFooter();
|
||||
|
||||
@@ -107,7 +107,7 @@ dol_fiche_head($head, 'card', $langs->trans("ThirdParty"),0,'company');
|
||||
|
||||
<tr>
|
||||
<td><?php echo $langs->trans('EMail'); ?></td>
|
||||
<td><?php echo $this->control->tpl['email'];; ?></td>
|
||||
<td><?php echo $this->control->tpl['email']; ?></td>
|
||||
<td><?php echo $langs->trans('Web'); ?></td>
|
||||
<td><?php echo $this->control->tpl['url']; ?></td>
|
||||
</tr>
|
||||
|
||||
@@ -106,7 +106,7 @@ dol_fiche_head($head, 'card', $langs->trans("ThirdParty"),0,'company');
|
||||
|
||||
<tr>
|
||||
<td><?php echo $langs->trans('EMail'); ?></td>
|
||||
<td><?php echo $this->control->tpl['email'];; ?></td>
|
||||
<td><?php echo $this->control->tpl['email']; ?></td>
|
||||
<td><?php echo $langs->trans('Web'); ?></td>
|
||||
<td><?php echo $this->control->tpl['url']; ?></td>
|
||||
</tr>
|
||||
|
||||
@@ -160,6 +160,6 @@ echo '</pre>';
|
||||
echo '<h4>SOAP Message</h4>';
|
||||
echo '<pre>' . htmlspecialchars($soapclient->response, ENT_QUOTES) . '</pre>';
|
||||
|
||||
echo '</body>'."\n";;
|
||||
echo '</html>'."\n";;
|
||||
echo '</body>'."\n";
|
||||
echo '</html>'."\n";
|
||||
?>
|
||||
|
||||
@@ -92,6 +92,6 @@ echo '<h4>SOAP Message</h4>';
|
||||
echo '<pre>' . htmlspecialchars($soapclient->response, ENT_QUOTES) . '</pre>';
|
||||
|
||||
|
||||
echo '</body>'."\n";;
|
||||
echo '</html>'."\n";;
|
||||
echo '</body>'."\n";
|
||||
echo '</html>'."\n";
|
||||
?>
|
||||
|
||||
@@ -136,6 +136,6 @@ echo '</pre>';
|
||||
echo '<h4>SOAP Message</h4>';
|
||||
echo '<pre>' . htmlspecialchars($soapclient2->response, ENT_QUOTES) . '</pre>';
|
||||
|
||||
echo '</body>'."\n";;
|
||||
echo '</html>'."\n";;
|
||||
echo '</body>'."\n";
|
||||
echo '</html>'."\n";
|
||||
?>
|
||||
|
||||
@@ -99,6 +99,6 @@ echo '</pre>';
|
||||
echo '<h4>SOAP Message</h4>';
|
||||
echo '<pre>' . htmlspecialchars($soapclient->response, ENT_QUOTES) . '</pre>';
|
||||
|
||||
echo '</body>'."\n";;
|
||||
echo '</html>'."\n";;
|
||||
echo '</body>'."\n";
|
||||
echo '</html>'."\n";
|
||||
?>
|
||||
|
||||
@@ -177,6 +177,6 @@ echo '</pre>';
|
||||
echo '<h4>SOAP Message</h4>';
|
||||
echo '<pre>' . htmlspecialchars($soapclient3->response, ENT_QUOTES) . '</pre>';
|
||||
|
||||
echo '</body>'."\n";;
|
||||
echo '</html>'."\n";;
|
||||
echo '</body>'."\n";
|
||||
echo '</html>'."\n";
|
||||
?>
|
||||
|
||||
@@ -223,6 +223,6 @@ echo '</pre>';
|
||||
echo '<h4>SOAP Message</h4>';
|
||||
echo '<pre>' . htmlspecialchars($soapclient->response, ENT_QUOTES) . '</pre>';
|
||||
|
||||
echo '</body>'."\n";;
|
||||
echo '</html>'."\n";;
|
||||
echo '</body>'."\n";
|
||||
echo '</html>'."\n";
|
||||
?>
|
||||
|
||||
@@ -116,7 +116,7 @@ if ($resql)
|
||||
$oldemail = $obj->email;
|
||||
$olduid = $obj->uid;
|
||||
$oldlang = $obj->lang;
|
||||
$oldsalerepresentative=dolGetFirstLastname($obj->firstname, $obj->lastname);;
|
||||
$oldsalerepresentative=dolGetFirstLastname($obj->firstname, $obj->lastname);
|
||||
$message = '';
|
||||
$total = 0;
|
||||
$foundtoprocess = 0;
|
||||
|
||||
@@ -120,7 +120,7 @@ if ($resql)
|
||||
$oldemail = $obj->email;
|
||||
$olduid = $obj->uid;
|
||||
$oldlang = $obj->lang;
|
||||
$oldsalerepresentative=dolGetFirstLastname($obj->firstname, $obj->lastname);;
|
||||
$oldsalerepresentative=dolGetFirstLastname($obj->firstname, $obj->lastname);
|
||||
$message = '';
|
||||
$total = 0;
|
||||
$foundtoprocess = 0;
|
||||
|
||||
Reference in New Issue
Block a user