<?php
/**
* p01-contact - A simple contact forms manager
*
* @link http://nliautaud.fr/wiki/travaux/getsimple_p01-contact Documentation
* @link http://get-simple.info/extend/plugin/p01-contact/35 Latest Version
* @author Nicolas Liautaud <contact@nliautaud.fr>
* @package p01-contact
* @version 0.9.1
*/
if(session_id()=='') session_start();
class P01contact
{
public $version;
public $default_email;
public $default_lang;
public $securimage_url;
private $forms;
public function __construct()
{
$this->version = '0.9.1';
$this->forms = array();
$dir = dirname(__FILE__);
define('LANGPATH', $dir . '/lang/');
define('CONFIGPATH', $dir . '/config.php');
define('CAPTCHAPATH', $dir . '/captcha/');
define('DOCURL', 'http://nliautaud.fr/wiki/travaux/p01-contact');
define('DOWNURL', 'http://get-simple.info/extend/plugin/p01-contact/35');
define('FORUMURL', 'http://get-simple.info/forum/topic/1108');
define('VERSIONURL', 'http://get-simple.info/api/extend/?id=35');
}
/**
* Parse a string to replace tags by forms
*
* Find tags, create forms structures, check POST and modify string.
* @param string $contents the string to parse
* @return string the modified string
*/
public function parse($contents)
{
$pattern = '`(?<!<code>)\(%\s*contact\s*(.*)\s*%\)`';
preg_match_all($pattern, $contents, $tags, PREG_SET_ORDER);
$ids = array();
// create forms structures from TAG
foreach($tags as $tag) {
$id = $this->new_form_id();
$form = $this->parse_tag($id, $tag[1]);
$this->forms[$id] = $form;
$ids[] = $id; // forms manipulated by this parsing session
}
// modify forms structures from POST, send mail
if(!empty($_POST['p01-contact_form'])) {
$this->post();
}
// replace tags by forms
foreach($ids as $id) {
$contents = preg_replace($pattern, $this->forms[$id]->html(), $contents, 1);
}
return $contents;
}
private function format($str)
{
$str = trim(preg_replace(
array('` `','`"`'),
array(' ','"'),
$str)
);
return $str;
}
/**
* Parse a tag to create form structure
*
* Find emails and parameters, create and setup form object.
* @param int $id the form id
* @param string $tag the tag to parse
* @return P01contact_form the form object
*/
private function parse_tag($id, $tag)
{
$form = new P01contact_form($this, $id);
$tag = $this->format($tag);
$param_pattern = '`[,:]\s*([^ ,"=!]+)(!)?\s*("([^"]*)")?\s*((=>|=)?\s*([^,]*))?\s*`';
$targets_pattern = '`[,:]\s*([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))`i';
$values_pattern = '`(?:^|\|)\s*(?:"([^"]+)")?\s*([^| ]+)?`';
// parse emails
preg_match_all($targets_pattern, $tag, $targets);
$targets = array_unique($targets[1]);
// add targets
if(empty($targets)) {
$default_email = $this->get_default_email();
if($default_email)
$form->add_target($default_email);
} else {
$form->set_targets($targets);
}
// delete them from tag
$rest = preg_replace($targets_pattern, '', $tag);
$rest = $this->format($rest);
// parse parameters
preg_match_all($param_pattern, $rest, $params, PREG_SET_ORDER);
if(empty($params)) {
$default = $this->settings('default_params');
$default = $this->format($default);
preg_match_all($param_pattern, ': ' . $default, $params, PREG_SET_ORDER);
}
// add fields
foreach($params as $id => $param) {
$field = new P01contact_field($form, $id, $param[1]);
$field->set_title($param[4]);
if($param[1] == 'select'
|| $param[1] == 'radio'
|| $param[1] == 'checkbox') {
// fields with multiples values
preg_match_all($values_pattern, $param[7], $values, PREG_SET_ORDER);
$values = unset_r($values, 0);
$field->set_value($values);
}
elseif($param[1] == 'askcopy') {
// create checkbox-like structure
$field->set_value(array(array(1 => $this->lang('askcopy'))));
}
elseif($param[1] == 'password') {
// password value is required value
$field->set_required($param[7]);
}
else $field->set_value($param[7]);
if($param[1] != 'password')
$field->set_required($param[2] == '!' ? True : False);
$field->set_locked($param[6] == '=>' ? True : False);
$form->add_field($field);
}
return $form;
}
/**
* Update POSTed form and try to send mail
*
* Check posted data, update form data,
* define fields errors and form status.
* At least, if there is no errors, try to send mail.
*/
private function post()
{
// check posted data and update form data
$form_id = $_POST['p01-contact_form']['id'];
if(isset($this->forms[$form_id]))
{
$form = $this->forms[$form_id];
foreach($this->format_data($_POST['p01-contact_fields']) as $field_id => $field_post)
{
$field = $form->get_field($field_id);
// for multiple-values fields, posted value define selection
$value = $field->get_value();
if(is_array($value)) {
// selections need to be an array
if(!is_array($field_post)) $selections = array($field_post);
else $selections = $field_post;
// reset value selection
foreach($value as $key => $val) {
$value[$key][2] = '';
}
// set value selection from POST
foreach($selections as $selection) {
foreach($value as $key => $val) {
if(trim($val[1]) == trim($selection))
$value[$key][2] = 'selected';
}
}
$field->set_value($value);
}
// for unique value fields, posted value define value
else $field->set_value($field_post);
$check = $field->check_content();
$field->set_error($check);
if($check) $errors = True;
}
// SECURITY : check tokens
if(!$this->check_token()) {
$form->set_status('token');
$this->set_token();
$form->reset();
}
// try to send mail
elseif(!isset($errors)) {
if($this->settings('enable') === False) {
$form->set_status('disable');
} elseif($form->count_targets() == 0) {
$form->set_status('target');
} else {
$form->send_mail();
$this->set_token();
$form->reset();
}
}
}
}
/**
* Return next accessible form ID
* @param string $key the setting key
* @return mixed the setting value
*/
private function new_form_id()
{
end($this->forms);
$id = key($this->forms) + 1;
reset($this->forms);
return $id;
}
/**
* Print POST and p01-contact content.
*/
public function debug()
{
ini_set('display_errors', 'on');
error_reporting(E_ALL);
echo'<h2 style="color:#c33">p01-contact debug</h2>';
if(!empty($_POST)) {
echo'<h3>$_POST :</h3>';
echo'<pre>';
@print_r($_POST);
echo'</pre>';
}
echo'<h3>$p01contact :</h3>';
echo'<pre>';
print_r($this);
echo'</pre>';
}
/**
* Return a setting value from config file
* @param string $key the setting key
* @return mixed the setting value
*/
public function settings($key)
{
require CONFIGPATH;
if(isset($p01contact_settings[$key]))
return $p01contact_settings[$key];
}
/**
* Format array values
*
* For aesthetic and security, and recursive.
* @param array $array
* @return array
*/
private function format_data($array)
{
foreach($array as $key => $val) {
if(is_array($val)) $this->format_data($array[$key]);
else {
$tmp = stripslashes($val);
$tmp = htmlentities($tmp, ENT_QUOTES, 'UTF-8');
$array[$key] = $tmp;
}
}
return $array;
}
/**
* Return a traduction of the keyword
*
* Manage languages between requested langs and existing traductions.
* @param string $key the keyword
* @return string
*/
public function lang($key)
{
global $p01contact_lang;
$lang = $this->settings('lang');
$lang = empty($lang) ? $this->default_lang : $lang;
$path = LANGPATH . $lang . '.php';
$lang = file_exists($path) ? $lang : 'en';
include_once $path;
if(isset($p01contact_lang[$key])) {
return $p01contact_lang[$key];
} else {
return ucfirst($key);
}
}
/**
* Return list of existing langs from lang/langs.php
* @return array
*/
private function langs()
{
require LANGPATH . '/langs.php';
return $p01contact_langs;
}
/**
* Return the last version of p01-contact in GS
* @return string
*/
private function last_version()
{
$apiback = file_get_contents(VERSIONURL);
$response = json_decode($apiback);
if ($response->status == 'successful') {
return $response->version;
}
}
/**
* Check if a new version exists. Return version number if exists, or False.
* @return mixed
*/
private function exists_new_version()
{
$actual = explode('.', $this->version);
$last = $this->last_version();
$last_r = explode('.', $last);
foreach($actual as $key => $val)
if(isset($last_r[$key])
&& $val < $last_r[$key])
return $last;
return False;
}
/**
* Save settings if necessary and display configuration panel content
* Parse and replace values in php config file by POST values.
*/
public function panel()
{
if(isset($_POST['p01-contact']['settings'])) {
$data = $this->format_data($_POST['p01-contact']['settings']);
if($content = file_get_contents(CONFIGPATH)) {
$enable = isset($data['enable']) ? 'True' : 'False';
$content = preg_replace("`('enable' => )(True|False)`", "\\1$enable", $content);
$debug = isset($data['debug']) ? 'True' : 'False';
$content = preg_replace("`('debug' => )(True|False)`", "\\1$debug", $content);
$content = preg_replace("`('lang' => ')[a-z]*'`", "\\1{$data['lang']}'", $content);
$content = preg_replace("`('default_params' => ')[^']*'`", "\\1{$data['default_params']}'", $content);
$content = preg_replace("`('default_email' => ')[^']*'`", "\\1{$data['default_email']}'", $content);
$content = preg_replace("`'message_len' => [0-9]+`", "'message_len' => {$data['message_len']}", $content);
foreach($data['checklist'] as $key => $val) {
$content = preg_replace("`('checklist_$key' => ')[^']*'`", "\\1$val'", $content);
}
if(file_exists(CONFIGPATH)
&& $file = fopen(CONFIGPATH, 'w')) {
fwrite($file, $content);
fclose($file);
global $p01contact_settings;
require(CONFIGPATH);
$updated = '<div class="updated">' . $this->lang('config_updated') . '</div>';
} else {
$error = $this->lang('config_error_modify');
}
} else {
$error = $this->lang('config_error_open');
}
}
if(isset($updated)) echo $updated;
elseif(isset($errors)) {
echo '<div class="error">' . $error . '<pre>' . CONFIGPATH . '</pre></div>';
}
echo $this->panel_content();
}
/**
* Return configuration panel content
*
* Display informations, parse config file and display settings form.
* @return string
*/
private function panel_content()
{
global $p01contact_settings;
$config_file = file_get_contents(CONFIGPATH, true); //true: use_include_path
$pattern = '`/\*[^*]*\* ([^*]*).*\* ([^*]*)[^*]*(\* ([^*]*))?\*/`';
preg_match_all($pattern, $config_file, $descs);
$c = '<h2>' . $this->lang('config_title') . '</h2>';
//new release
if($newversion = $this->exists_new_version()) {
$c.= '<div class="updated">' . $this->lang('new_release');
$c.= '<br /><a href="' . DOWNURL . '">';
$c.= $this->lang('download') . ' (' . $newversion . ')</a></div>';
}
//links
$c.= '<p><a href="' . DOCURL . '">' . $this->lang('doc') . '</a>';
$c.= ' - <a href="' . FORUMURL . '">' . $this->lang('forum') . '</a></p>';
$c.= '<form action="" method="post"><table>';
//enable
$c.= '<tr><td><b><label style="display:block;float:none">' . $this->lang('enable') . '</label></b>';
$c.= '<i>' . $this->lang('enable_sub') . '</i></td>';
$c.= '<td><input type="checkbox" name="p01-contact[settings][enable]" ';
$c.= $this->settings('enable') ? 'checked="checked" ' : '';
$c.= '/></td></tr>';
//default email
$c.= '<tr><td><b><label style="display:block;float:none">';
$c.= $this->lang('default_email') . '</label></b>';
$c.= '<i>' . $this->lang('default_email_sub') . ' ';
$c.= ($this->default_email ? $this->default_email : '"not set"') . '</i></td><td>';
$c.= '<input type="text" name="p01-contact[settings][default_email]" ';
$settings_email = $this->settings('default_email');
$c.= 'value="' . $settings_email . '" />';
$c.= '</td></tr>';
// language
$c.= '<tr><td><b><label style="display:block;float:none">' . $this->lang('lang') . '</label></b>';
$c.= '<i>' . $this->lang('lang_sub') . ' ' . $this->default_lang . '</i></td>';
$c.= '</td><td><select name="p01-contact[settings][lang]">';
$lang = $this->settings('lang');
$c.= '<option value=""' . ($lang == ''?' selected="selected" ':'') . '>Default</option>';
foreach($this->langs() as $iso => $name) {
$c.= '<option value="' . $iso . '" ';
if($lang == $iso) $c.= 'selected="selected" ';
$c.= '/>' . $name . '</option>';
}
$c.= '</select></td></tr>';
//message length
$c.= '<tr><td><b><label style="display:block;float:none">' . $this->lang('message_len') . '</label></b>';
$c.= '<i>' . $this->lang('message_len_sub') . '</i></td>';
$c.= '<td><input type="text" name="p01-contact[settings][message_len]" size=3 maxlength=3 ';
$c.= 'value="' . $this->settings('message_len').'" /></td></tr>';
// default parameters
$c.= '<tr><td colspan="2"><b><label style="display:block;float:none">';
$c.= $this->lang('default_params') . '</label></b>';
$c.= '<i>' . $this->lang('default_params_sub') . '</i><br />';
$c.= '<textarea name="p01-contact[settings][default_params]" style="width:100%;height:40px">';
$c.= $this->settings('default_params');
$c.= '</textarea></td></tr>';
//checklists
$c.= '<tr><td colspan="2"><b><label style="display:block;float:none">';
$c.= $this->lang('checklists') . '</label></b>';
$c.= '<i>' . $this->lang('checklists_sub') . '</i>';
$fields = array(
'general_fields' => array('text','textarea'), 'special_fields' =>
array('name','email','address','phone','website','subject','message'));
foreach($fields as $type => $f)
foreach($f as $id=>$field) {
if(!$id) $c.= '<p></p><p><b>' . $this->lang($type) . ' :</b></p>';
$content = $this->settings('checklist_'.$field);
$c.= '<div><b>' . ucfirst($field);
$c.= ' </b><input name="p01-contact[settings][checklist_type]['.$field.']"';
$c.= ' type="radio" value="blacklist" checked /> ' . $this->lang('blacklist');
$c.= ' <input name="p01-contact[settings][checklist_type]['.$field.']"';
$c.= ' type="radio" value="whitelist" disabled /> ' . $this->lang('whitelist') . '</div>';
$c.= '<textarea name="p01-contact[settings][checklist]['.$field.']" ';
$c.= 'style="width:100%;height:'.(40+strlen($content)*0.2).'px">';
$c.= $content . '</textarea>';
}
$c.= '</tr></td>';
//debug
$c.= '<tr><td><b><label style="display:block;float:none">' . $this->lang('debug') . '</label></b>';
$c.= '<i>' . $this->lang('debug_sub') . '</i><br />';
$c.= '<b>' . $this->lang('debug_warn') . '</b></td>';
$c.= '<td><input type="checkbox" name="p01-contact[settings][debug]" ';
$c.= $this->settings('debug') ? 'checked="checked" ' : '';
$c.= '/></td></tr>';
$c.= '<tr><td><input type="submit" value="' . $this->lang('save_set') . '" /></td></tr>';
$c.= '</table></form>';
return $c;
}
/*
* Create an unique hash in SESSION
*/
private function set_token()
{
$_SESSION['p01-contact_token'] = uniqid(md5(microtime()), True);
}
/*
* Get the token in SESSION (create it if not exists)
* @return string
*/
public function get_token()
{
if(!isset($_SESSION['p01-contact_token']))
$this->set_token();
return $_SESSION['p01-contact_token'];
}
/*
* Compare the POSTed token to the SESSION one
* @return boolean
*/
private function check_token()
{
if($this->get_token() === $_POST['p01-contact_form']['token'])
return True;
else return False;
}
/*
* Return settings default email if set and valid,
* or $this->default_email if set and valid,
* or False.
*/
public function get_default_email()
{
$settings_email = $this->settings('default_email');
$pattern = '`^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$`i';
if(!empty($settings_email)
&& preg_match($pattern, $settings_email))
return $settings_email;
if(!empty($this->default_email)
&& preg_match($pattern, $this->default_email))
return $this->default_email;
return False;
}
}
/*
* Contact form class
* Contains fields, manage mail sending.
*/
class P01contact_form
{
public $P01contact;
private $id;
private $status;
private $targets;
private $fields;
/*
* @param P01contact $P01contact
* @param int $id the form id
*/
public function __construct($P01contact, $id)
{
$this->P01contact = $P01contact;
$this->id = $id;
$this->status = '';
$this->targets = array();
$this->fields = array();
}
/*
* Return the html display of the form
* @return string the <form>
*/
public function html()
{
$html = '<form action="#p01-contact' . $this->id . '" autocomplete="off" ';
$html .= 'id="p01-contact' . $this->id . '" class="p01-contact" method="post">';
$html .= $this->html_status();
if($this->status != 'sent') {
foreach($this->fields as $id => $field) $html .= $field->html();
$html .= '<div class="otpr"><input name="p01-contact_form[id]" type="hidden" value="' . $this->id . '" />';
$html .= '<input name="p01-contact_form[token]" type="hidden" value="' . $this->P01contact->get_token() . '" />';
$html .= '<input class="submit" ';
$html .= 'type="submit" value="' . $this->lang('send') . '" /><p><span style="color:' . $this->lang('color') . '">*</span> ' . $this->lang('note') . '</p></div>';
}
$html .= '</form>';
return $html;
}
/*
* Return an html display of the form status
* @return string the <div>
*/
private function html_status()
{
if(!$this->status) return '';
$style = '
margin:20px 0 400px 0;
background:#FCFBB8;
line-height:30px;
padding:0 10px;
border:1px solid #F9CF51;
border-radius: 5px;
-moz-border-radius: 5px;
-khtml-border-radius: 5px;
-webkit-border-radius: 5px;';
$style .= $this->status == 'sent' ? 'color:#308000;' : 'color:#D94136;';
return '<div class="fix" style="'.$style.'">' . $this->lang($this->status) . '</div>';
}
/*
* Return an html http:// link
* @param string $href the link address
* @param string $title if not used, the link title will be the address
* @return string the <a>
*/
private function html_link($href, $title = False)
{
if(!$title) $title = $href;
return '<a href="http://' . $href . '">' . $title . '</a>';
}
/*
* Return an html mailto: link
* @param string $href the email
* @param string $title if not used, the link title will be the email
* @return string the <a>
*/
private function html_mail_link($href, $title = False)
{
if(!$title) $title = $href;
return '<a href="mailto:' . $href . '">' . $title . '</a>';
}
/**
* Send a mail based on form
*
* Create the mail content and headers along to settings, form
* and fields datas; and update the form status (sent|error).
*/
public function send_mail()
{
$server = $_SERVER['SERVER_NAME'];
$uri = $_SERVER['REQUEST_URI'];
// title
$content = '<h2>' . $this->lang('fromsite') . ' <i>' . $_SERVER['SERVER_NAME'] . '</i></h2>';
$content .= '<h3>' . date('r') . '</h3><br/>';
// fields
$skip = array('captcha');
foreach($this->fields as $field)
{
$type = $field->get_type();
$value = $field->get_value();
$title = $field->get_title();
if($type == 'name')
$name = $value;
elseif($type == 'email')
$email = $value;
elseif($type == 'subject')
$subject = $value;
elseif(
!in_array($type, $skip)
&& !empty($value))
{
$title = !empty($title) ? $title : $type;
if($type != 'askcopy') // managed blow for him.
$content .= '<p><b>' . $this->lang($title).' :</b> ';
switch($type)
{
case 'message' :
case 'textarea' :
$content .= '<p style="margin:10px;padding:10px;border:1px solid silver">';
$content .= nl2br($value) . '</p>';
break;
case 'website' :
$content .= $this->html_link($value);
break;
case 'checkbox' :
case 'select' :
case 'radio' :
$content .= '<ul>';
foreach($value as $v)
if(isset($v[2]) && $v[2] == 'selected')
$content .= '<li>' . $v[1] . '</li>';
$content .= '</ul>';
break;
case 'askcopy' :
$askcopy = True;
$content .= '<p><b>' . $this->lang('askedcopy').'.</b></p>';
break;
default :
$content .= $value;
}
$content .= '</p>';
}
}
if(!isset($askcopy)) $askcopy = False;
// footer infos
$footer = '<p><i>' . $this->lang('sentfrom');
$footer .= ' ' . $this->html_link($server.$uri, $uri);
$footer_copy = $footer . '</i></p>'; // version without infos below
$footer .= '<br />If this mail should not be for you, please contact ';
$footer .= $this->html_mail_link($this->P01contact->get_default_email());
$footer .= '</i></p>';
$targets = implode(',', $this->targets);
if(empty($name)) $name = $this->lang('nofrom');
if(empty($email)) {
$askcopy = False;
$email = $this->lang('nofrom');
}
if(empty($subject)) $subject = $this->lang('nosubject');
$subject = '=?utf-8?B?' . base64_encode($subject) . '?=';
$headers = "From: $name <$email>\r\n";
$headers .= "Reply-To: $name <$email>\r\n";
$headers .= "Return-Path: $name <$email>\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=UTF-8\r\n";
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n" ;
if(!$this->settings('debug')) {
// send mail
$status = mail($targets, $subject, $content.$footer, $headers);
if($status) {
if($askcopy) { // send copy
$copy = mail($email, $subject, $content.$footer_copy, $headers);
if($copy) $this->status = $this->lang('sent_copy');
else $this->status = $this->lang('error_copy');
} else $this->status = 'sent';
} else $this->status = 'error';
} else {
// display mail for debug
echo'<h2 style="color:#c33">p01-contact (not) sent mail :</h2>';
echo'<pre>' . $headers . '</pre>';
echo'<div style="border:1px solid black;padding:10px">' . $content.$footer . '</div>';
$this->status = $this->lang('debug');
}
}
/*
* Reset all fields values and errors
*/
public function reset()
{
foreach($this->fields as $id => $field) {
$field->set_value('');
$field->set_error('');
}
}
/**
* GETTERS / SETTERS
*/
public function add_target($tget) {$this->targets[] = $tget;}
public function set_targets(array $targets) {$this->targets = $targets;}
public function count_targets() {return count($this->targets);}
public function get_field($id) {return $this->fields[$id];}
public function get_fields() {return $this->fields;}
public function add_field(P01contact_field $field) {$this->fields[] = $field;}
public function set_status($status) {
if(is_string($status)) $this->status = $status;
}
public function get_id() {return $this->id;}
public function get_status() {return $this->status;}
public function settings($key) {return $this->P01contact->settings($key);}
public function lang($key) {return $this->P01contact->lang($key);}
}
class P01contact_field
{
private $form;
private $id;
private $type;
private $title;
private $value;
private $required;
private $locked;
private $error;
/*
* @param P01contact_form $form the container form
* @param int $id the field id
* @param string $type the field type
*/
public function __construct($form, $id, $type)
{
$this->form = $form;
$this->id = $id;
$this->type = $type;
$this->title = '';
$this->value = '';
$this->required = False;
$this->locked = False;
$this->error = '';
}
/**
* Check field value
*
* Check if field is empty and required or
* not empty but not valid.
* @return string the error key, or empty
*/
public function check_content()
{
if(empty($this->value) && $this->required) {
// empty and required
return 'field_required';
}
elseif(!empty($this->value) && !$this->check_validity()) {
// not empty but not valid
return 'field_' . $this->type;
}
else return '';
}
/**
* Check if field value is valid
* Mean different things depending on field type
* @return boolean
*/
public function check_validity()
{
if($this->blacklisted()) return False;
switch($this->type) {
case 'email':
$pattern = '`^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$`i';
if(preg_match($pattern, $this->value)) return True;
else return False;
case 'phone':
$pattern = '`^\+?[-0-9(). ]{6,}$$`i';
if(preg_match($pattern, $this->value)) return True;
else return False;
case 'website':
$pattern = "`^((http|https|ftp):\/\/(www\.)?|www\.)[a-zA-Z0-9\_\-]+\.([a-zA-Z]{2,4}|[a-zA-Z]{2}\.[a-zA-Z]{2})(\/[a-zA-Z0-9\-\._\?\&=,'\+%\$#~]*)*$`i";
if(preg_match($pattern, $this->value)) return 1;
else return False;
case 'message':
$size = strlen($this->value);
if($size > $this->form->settings('message_len')) return True;
else return False;
case 'captcha':
include_once CAPTCHAPATH . 'securimage.php';
$securimage = new Securimage();
if($securimage->check($this->value) == False)
return False;
else return True;
case 'fieldcaptcha':
if(!empty($this->value)) return False;
else return True;
case 'password':
if($this->value == $this->required)
return True;
else return False;
default:
return True;
}
}
/**
* Check if field value is blacklisted
*
* Search any entry of config file field type
* blacklist in field value.
* @return boolean
*/
public function blacklisted()
{
$list = $this->form->settings('checklist_' . $this->type);
if(empty($list)) return False;
$array = explode(',', $list);
foreach($array as $avoid) {
if(preg_match('`' . $avoid . '`', $this->value))
return True;
}
return False;
}
/*
* Return the html display of the field
*
* Manage field title, error message, and type-based display
* @return string the <div>
*/
public function html()
{
$id = 'p01-contact' . $this->form->get_id() . '_field' . $this->id;
$name = 'p01-contact_fields[' . $this->id . ']';
$type = $this->general_type();
$value = $this->value;
$disabled = $this->locked ? ' disabled="disabled"' : '';
$html = '
<div class="field ' . $type . '">';
if($this->type != 'askcopy') // not needed here, the value say everything
$html .= $this->html_label($id);
switch($type) {
case 'text' :
$html .= '
<input id="' . $id . '" ';
$html .= 'name="' . $name . '" type="text" ';
$html .= 'value="' . $value . '"' . $disabled . ' />';
break;
case 'textarea' :
$html .= '
<textarea id="' . $id . '" rows="10" ';
$html .= 'name="' . $name . '"' . $disabled;
$html .= '>' . $value . '</textarea>';
break;
case 'captcha' :
$html .= '
<div class="captchaimg">';
$html .= '<img id="captchaimg" ';
$html .= 'src="' . $this->securimage_url() . 'securimage_show.php" ';
$html .= 'alt="CAPTCHA Image" />';
$html .= '</div></label></div>
<input id="' . $id . '" ';
$html .= 'type="text" name="' . $name . '" ';
$html .= 'size="10" maxlength="6"' . $disabled . ' />
<a class="reload" href="#"';
$html .= ' onclick="document.getElementById(\'captchaimg\').src = ';
$html .= '\'' . $this->securimage_url() . 'securimage_show.php?\' ';
$html .= '+ Math.random(); return false">';
$html .= $this->form->lang('reload');
$html .= '</a>';
break;
case 'fieldcaptcha' :
$html .= '<input id="' . $id . '" type="text" name="' . $name . '" />';
break;
case 'checkbox' :
foreach($this->value as $i => $v) {
$value = !empty($v[1]) ? ' ' . $v[1] : '';
$selected = !empty($v[2]) && $v[2] == 'selected' ? ' checked' : '';
$html .= '
<input id="' . $id . '_option' . $i . '"';
$html .= ' type="checkbox" name="' . $name . '[' . $i . ']"';
$html .= ' value="' . $value . '"' . $disabled . $selected;
$html .= ' />' . $value;
}
break;
case 'select' :
$html .= '
<select id="' . $id . '" name="' . $name . '"' . $disabled . '>';
foreach($this->value as $i => $v) {
$value = !empty($v[1]) ? ' ' . $v[1] : ' Default';
$selected = !empty($v[2]) && $v[2] == 'selected' ? 'selected="selected"' : '';
$html .= '
<option id="' . $id . '_option' . $i . '" value="' . $value;
$html .= '"' . $selected . ' >' . $value . '</option>';
}
$html.= '</select>';
break;
case 'radio' :
foreach($this->value as $i => $v) {
$value = !empty($v[1]) ? ' ' . $v[1] : ' Default';
$selected = !empty($v[2]) && $v[2] == 'selected' ? ' checked' : '';
$html .= '
<input id="' . $id . '_option' . $i . '" type="radio" ';
$html .= 'name="' . $name . '" value="' . $value . '"';
$html .= $disabled . $selected . ' />' . $value;
}
break;
case 'password' :
$html .= '
<input id="' . $id . '" ';
$html .= 'name="' . $name . '" type="password" ';
$html .= $disabled . ' />';
break;
case 'file' :
$html .= '<input id="' . $id . '" ';
$html .= 'type="file" name="' . $name . '" />';
break;
}
$html .= '</div>';
return $html;
}
/*
* Return the label of the field
* @param string $for id of the target field
* @return string the <div> (unclosed for captcha)
*/
private function html_label($for)
{
$html = '
<div class="label">';
$html .= '<label for="' . $for . '">';
if(!empty($this->title)) {
$html .= $this->title;
} else $html .= ucfirst($this->form->lang($this->type));
$html .= $this->required ? ' <strong style="color:red">*</strong>' : '';
if(!empty($this->error)) {
$html .= ' <span style="font-size:0.9em;color:red">';
$html .= $this->form->lang($this->error);
$html .= '</span>';
}
if($this->type != 'captcha') { // captcha close label after image
$html .= '</label></div>';
}
return $html;
}
/**
* Return the general type of a field, even of specials fields.
*/
function general_type()
{
$types = array(
'name' => 'text',
'email' => 'text',
'phone' => 'text',
'website' => 'text',
'subject' => 'text',
'address' => 'textarea',
'message' => 'textarea',
'file' => 'file',
'captcha' => 'captcha',
'askcopy' => 'checkbox');
if(isset($types[$this->type]))
return $types[$this->type];
else return $this->type;
}
/**
* GETTERS / SETTERS
*/
public function get_type() {return $this->type;}
public function get_title() {return $this->title;}
public function set_title($title) {
if(is_string($title)) $this->title = $title;
}
public function get_value() {return $this->value;}
public function set_value($value) {
if(is_string($value)
|| is_array($value))
$this->value = $value;
}
public function set_required($required) {
$this->required = $required;
}
public function set_locked($locked) {
if(is_bool($locked)) $this->locked = $locked;
}
public function set_error($error) {
if(is_string($error)) $this->error = $error;
}
public function securimage_url() {
return $this->form->P01contact->securimage_url;
}
}
function preint($arr) {echo'<pre>';var_dump($arr);echo'</pre>';}
function unset_r($a,$i) {
foreach($a as $k=>$v)
if(isset($v[$i]))
unset($a[$k][$i]);
return $a;
}
?>