Record Class
The deletion prompt template for items based on the Record class can be set by the snippet parameter &deleteForm=`<chunk name>`, otherwise it defaults to pk.item.delete.tpl
Some of the validation options are for record types not currently included in the package, such as response forms.
<?php
class Record
// general class for custom DB records
{
public $recordType = 'record';
public $lang;
public $delForm = 'pk.item.delete.tpl';
public $tvs = array();
function __construct($pid=0, $fields=array(), $lang) {
// set up table and field names
global $modx, $table_prefix;
$this->table = $table_prefix . $this->table;
if (isset($fields['params']['tvs'])) {
$tvDefs = explode(';', $fields['params']['tvs']);
foreach ($tvDefs as $tvDef) {
$tvElements = explode(',', $tvDef);
$tvName = trim($tvElements[0]);
$this->tvs[$tvName]['column'] = $tvElements[1];
$this->tvs[$tvName]['field'] = isset($tvElements[2]) ? $tvElements[2] : $tvName;
$this->tvs[$tvName]['format'] = $tvElements[3];
}
}
if (!empty ($pid)) {
$this->Populate($pid);
}
$this->lang = $lang;
if (isset($fields['params']['deleteForm'])) {
$this->delForm = $fields['params']['deleteForm'];
}
if (isset($fields['params']['deleteMessage'])) {
$this->delMsg = $fields['params']['deleteMessage'];
}
}
function Populate($pid) {
// retrieve field values from DB
global $modx;
$record = $modx->db->select('*',
$this->table,
"id = $pid ",
$this->sortOrder);
$item = $modx->db->getRow($record);
if (!empty($item)) {
foreach ($item as $key=>$column) {
$this->$key = $column;
}
}
return;
}
function Save($pid=NULL, $fields=array()) {
global $modx;
$this->id = $pid;
$newRecord = empty($pid);
$fields['updated'] = strftime('%Y-%m-%d %H:%M:%S');
// translate field names to column names for TVs
if (isset($this->tvs)) {
foreach ($this->tvs as $tv) {
$tvField = $tv['field'];
$tvColumn = $tv['column'];
if ($tvField !== $tvColumn && isset($fields[$tvField])) {
$fields[$tvColumn] = $fields[$tvField];
}
}
}
foreach ($fields as $key=>$field) {
if (in_array($key, $this->columns)) {
if (is_array($field)) {
$field = implode("||",$field);
}
$dbFields[$key] = $modx->db->escape($field);
}
}
if ($newRecord) {
if (property_exists($this->name, 'nsId')) {
$dbFields['id'] = $this->nsId;
$modx->db->insert($dbFields, $this->table);
$pid = $this->nsId;
} else {
$modx->db->insert($dbFields, $this->table);
$pid = mysql_insert_id();
}
} else {
$modx->db->update($dbFields, $this->table, "id = '$pid'");
}
$this->populate($pid);
return $pid;
}
function Delete($pid) {
global $modx;
$modx->db->delete($this->table,"id = '$pid'");
if (property_exists($this, 'rank')) {
resetFormRank($this->table, 1, $this->sortOrder);
}
return;
}
function CheckFields($fields) {
$errors = array();
foreach ($this->validate as $field=>$rules) {
if (!is_array($rules)) {
$rules = array($rules);
}
foreach ($rules as $rule) {
$newErrors = $this->CheckOneField($fields, $field, $rule);
$errors = array_merge($errors, $newErrors);
}
}
return $errors;
}
function CheckOneField($fields, $field, $rule) {
global $modx;
$lang = $this->lang;
$errors = array();
$curField = $fields[$field];
$features = explode('||',$rule);
switch ($features[0]) {
case 'string':
if (($features[1] == 'Req') && (strlen(trim($curField)) < 1)) {
$errors[] = $lang['err_' . $features[2] ];
}
break;
case 'date':
if ($features[1] == 'Req' && strlen($curField) < 1) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_blank'];
}
elseif (!empty($curField)
AND strtotime($curField) === FALSE) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_dateFormat'];
}
break;
case 'time':
if ($features[1] == 'Req' && strlen($curField) < 1) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_blank'];
}
elseif (timeValid($curField) === FALSE) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_timeFormat'];
}
break;
case 'email':
if (!empty($curField)
&& preg_match('/^.+@.+\..{2,3}$/',$curField) < 1) {
$errors[] = $lang['err_emailFormat'];
}
break;
case 'phone':
if (!empty($curField)
&& preg_match('/[0-9\- ]+/', $curField) < 1) {
$errors[] = $lang['err_phoneFormat'];
}
break;
case 'alt':
// test for valid email OR phone number
$replyFields = 0;
if (!empty($fields['email'])) {
$replyFields++;
if (preg_match('/^.+@.+\..{2,3}$/',$fields['email']) < 1) {
$errors[] = $lang['err_emailFormat'];
}
}
if (strlen($fields['phone']) > 1) {
$replyFields++;
if (preg_match('/[^0-9\(\)\-\+]+/', $fields['phone']) > 0) {
$errors[] = $lang['err_phoneFormat'];
}
}
if ($replyFields < 1) {
$errors[] = $lang['err_msgReply'];
}
break;
case 'badwords':
$bad = strtolower($modx->getChunk('badwords'));
if (!empty($bad)) {
$badWords = explode(",", $bad);
$msgWords = str_word_count(strtolower($curField), 1, '[');
if ($features[1] == 'Req') {
foreach($msgWords as $msgWord) {
if (in_array($msgWord, $badWords)) {
$err = (isset($features[2])) ? 'err_' . $features[2] : 'err_badwords';
$errors[] = $lang[$err];
$this->Alert($fields, FALSE, 'content');
break;
}
}
}
}
break;
case 'token':
if (!isset($_SESSION[$field]) || empty($curField) || $curField !== $_SESSION[$field]) {
$errors[] = $lang['err_secureForm'];
unset($_SESSION[$field]);
$this->Alert($fields, FALSE, 'token');
}
break;
}
return $errors;
}
function Alert($fields,$successful=TRUE, $reason=NULL) {
// dummy function for classes with no email routines, in case 'token' is validated
// you could have an email to an admin here, or a logging action
}
}
?>
class Record
// general class for custom DB records
{
public $recordType = 'record';
public $lang;
public $delForm = 'pk.item.delete.tpl';
public $tvs = array();
function __construct($pid=0, $fields=array(), $lang) {
// set up table and field names
global $modx, $table_prefix;
$this->table = $table_prefix . $this->table;
if (isset($fields['params']['tvs'])) {
$tvDefs = explode(';', $fields['params']['tvs']);
foreach ($tvDefs as $tvDef) {
$tvElements = explode(',', $tvDef);
$tvName = trim($tvElements[0]);
$this->tvs[$tvName]['column'] = $tvElements[1];
$this->tvs[$tvName]['field'] = isset($tvElements[2]) ? $tvElements[2] : $tvName;
$this->tvs[$tvName]['format'] = $tvElements[3];
}
}
if (!empty ($pid)) {
$this->Populate($pid);
}
$this->lang = $lang;
if (isset($fields['params']['deleteForm'])) {
$this->delForm = $fields['params']['deleteForm'];
}
if (isset($fields['params']['deleteMessage'])) {
$this->delMsg = $fields['params']['deleteMessage'];
}
}
function Populate($pid) {
// retrieve field values from DB
global $modx;
$record = $modx->db->select('*',
$this->table,
"id = $pid ",
$this->sortOrder);
$item = $modx->db->getRow($record);
if (!empty($item)) {
foreach ($item as $key=>$column) {
$this->$key = $column;
}
}
return;
}
function Save($pid=NULL, $fields=array()) {
global $modx;
$this->id = $pid;
$newRecord = empty($pid);
$fields['updated'] = strftime('%Y-%m-%d %H:%M:%S');
// translate field names to column names for TVs
if (isset($this->tvs)) {
foreach ($this->tvs as $tv) {
$tvField = $tv['field'];
$tvColumn = $tv['column'];
if ($tvField !== $tvColumn && isset($fields[$tvField])) {
$fields[$tvColumn] = $fields[$tvField];
}
}
}
foreach ($fields as $key=>$field) {
if (in_array($key, $this->columns)) {
if (is_array($field)) {
$field = implode("||",$field);
}
$dbFields[$key] = $modx->db->escape($field);
}
}
if ($newRecord) {
if (property_exists($this->name, 'nsId')) {
$dbFields['id'] = $this->nsId;
$modx->db->insert($dbFields, $this->table);
$pid = $this->nsId;
} else {
$modx->db->insert($dbFields, $this->table);
$pid = mysql_insert_id();
}
} else {
$modx->db->update($dbFields, $this->table, "id = '$pid'");
}
$this->populate($pid);
return $pid;
}
function Delete($pid) {
global $modx;
$modx->db->delete($this->table,"id = '$pid'");
if (property_exists($this, 'rank')) {
resetFormRank($this->table, 1, $this->sortOrder);
}
return;
}
function CheckFields($fields) {
$errors = array();
foreach ($this->validate as $field=>$rules) {
if (!is_array($rules)) {
$rules = array($rules);
}
foreach ($rules as $rule) {
$newErrors = $this->CheckOneField($fields, $field, $rule);
$errors = array_merge($errors, $newErrors);
}
}
return $errors;
}
function CheckOneField($fields, $field, $rule) {
global $modx;
$lang = $this->lang;
$errors = array();
$curField = $fields[$field];
$features = explode('||',$rule);
switch ($features[0]) {
case 'string':
if (($features[1] == 'Req') && (strlen(trim($curField)) < 1)) {
$errors[] = $lang['err_' . $features[2] ];
}
break;
case 'date':
if ($features[1] == 'Req' && strlen($curField) < 1) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_blank'];
}
elseif (!empty($curField)
AND strtotime($curField) === FALSE) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_dateFormat'];
}
break;
case 'time':
if ($features[1] == 'Req' && strlen($curField) < 1) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_blank'];
}
elseif (timeValid($curField) === FALSE) {
$errors[] = $lang[$features[2] ] . ': ' . $lang['err_timeFormat'];
}
break;
case 'email':
if (!empty($curField)
&& preg_match('/^.+@.+\..{2,3}$/',$curField) < 1) {
$errors[] = $lang['err_emailFormat'];
}
break;
case 'phone':
if (!empty($curField)
&& preg_match('/[0-9\- ]+/', $curField) < 1) {
$errors[] = $lang['err_phoneFormat'];
}
break;
case 'alt':
// test for valid email OR phone number
$replyFields = 0;
if (!empty($fields['email'])) {
$replyFields++;
if (preg_match('/^.+@.+\..{2,3}$/',$fields['email']) < 1) {
$errors[] = $lang['err_emailFormat'];
}
}
if (strlen($fields['phone']) > 1) {
$replyFields++;
if (preg_match('/[^0-9\(\)\-\+]+/', $fields['phone']) > 0) {
$errors[] = $lang['err_phoneFormat'];
}
}
if ($replyFields < 1) {
$errors[] = $lang['err_msgReply'];
}
break;
case 'badwords':
$bad = strtolower($modx->getChunk('badwords'));
if (!empty($bad)) {
$badWords = explode(",", $bad);
$msgWords = str_word_count(strtolower($curField), 1, '[');
if ($features[1] == 'Req') {
foreach($msgWords as $msgWord) {
if (in_array($msgWord, $badWords)) {
$err = (isset($features[2])) ? 'err_' . $features[2] : 'err_badwords';
$errors[] = $lang[$err];
$this->Alert($fields, FALSE, 'content');
break;
}
}
}
}
break;
case 'token':
if (!isset($_SESSION[$field]) || empty($curField) || $curField !== $_SESSION[$field]) {
$errors[] = $lang['err_secureForm'];
unset($_SESSION[$field]);
$this->Alert($fields, FALSE, 'token');
}
break;
}
return $errors;
}
function Alert($fields,$successful=TRUE, $reason=NULL) {
// dummy function for classes with no email routines, in case 'token' is validated
// you could have an email to an admin here, or a logging action
}
}
?>