37 require_once realpath(dirname(__FILE__).
"/auto_form.inc");
69 function like($name, $value)
92 function from($name, $from)
104 function to($name, $to)
143 function any($name, $value)
156 function all($name, $value)
196 return "$name=$value";
199 function any($name, $value)
201 trace(
"NUMBER: ANY!!!", 3);
203 if (strpos($value,
",") !== FALSE)
205 $value = explode(
",", $value);
210 if (is_array($value))
212 if (count($value) == 0)
return "";
213 return "$name in (".implode(
",", array_values($value)).
") ";
215 else return "$name=$value";
220 die(
"Inappropriate matching mode");
225 die(
"Inappropriate matching mode");
231 return "$name >= $from";
234 function to($name, $to)
237 return "$name <= $to";
245 return "($name >= $from AND $name <= $to)";
258 trace(
"## NUMBERSEARCHPARAMETERHANDLER", 1);
262 $values = implode(
",", array_keys($set));
263 return "$name IN ($set)";
284 return "$name LIKE $txt";
290 return "$name LIKE $txt";
296 return "$name >= $txt";
299 function to($name, $to)
302 return "$name <= $txt";
310 return "($name >= $from AND $name <= $to)";
313 function any($name, $value)
315 $value = preg_replace(
"/\\s+/",
" ", $value);
316 $words = explode(
" ", $value);
318 if (count($words) == 0)
return;
322 foreach($words as $word)
325 if (!$first) $query .=
" OR ";
326 $query .=
"$name LIKE $txt";
334 function all($name, $value)
336 $value = preg_replace(
"/\\s+/",
" ", $value);
338 $words = explode(
" ", $value);
340 if (count($words) == 0)
return;
344 foreach($words as $word)
347 if (!$first) $query .=
" AND ";
348 $query .=
"$name LIKE $txt";
359 $value = preg_replace(
"/\\s+/",
" ", $value);
360 $words = explode(
" ", $value);
362 if(count($words) < 2)
return;
368 while($idx < count($words)-1)
370 if (!$first) $query .=
" OR (";
374 $query .=
"{$f_name} LIKE $txt1 AND {$l_name} LIKE $txt2";
391 trace(
"## STRINGSEARCHPARAMETERHANDLER", 1);
392 if(!$set || !isset($set))
return "";
397 $values =
"'". implode(
"','", array_keys($set)) .
"'";
401 $values =
"'".implode(
"','", explode(
",", $set)).
"'";
402 $values = preg_replace(
"/''/",
"'", $values);
405 return "$name IN ($values)";
421 if (preg_match(
"|^(\\d+)[\-/](\\d+)[\-/](\\d{4})$|", $date, $fields))
423 $date = $fields[3].
"-".$fields[1].
"-".$fields[2];
425 $date = date(
'Y-m-d', strtotime($date));
428 else if (preg_match(
"|^(\\d+)/(\\d+)/(\\d{4})\\s+(\\d+:\\d+:\\d+)|", $date, $fields))
431 $date = date(
'Y-m-d', strtotime($date));
432 $date = $fields[3].
"-".$fields[1].
"-".$fields[2].
" ".$fields[4];
442 return "$name='$date'";
448 die(
"Inappropriate matching mode");
453 die(
"Inappropriate matching mode");
460 return "$name >= '$from'";
463 function to($name, $to)
466 return "$name <= '$to'";
481 return "($name BETWEEN '$from' AND '$to')";
503 $values = implode(
",", array_keys($set));
505 if (!$set)
return "";
507 trace(
"## Generating cross reference terms for $name using values ($values)", 3);
511 $pk = $obj->getPrimaryKey();
513 return "$pk IN (SELECT {$pk} FROM {$xref->table} WHERE {$this->foreignKey} IN ($set))";
521 trace(
"FILTER: equal $name $value", 3);
524 return "$name=$value";
529 trace(
"FILTER: checked $name $value", 3);
531 $out = ($value) ?
"$name=$value" :
"";
532 trace(
"FILTER: out $out", 3);
568 private static $serializedFields = array(
"params",
"handlers",
"joinWith",
"secondaryFields",
"additional",
"empty");
571 return SearchParameters::$serializedFields;
576 $this->params = $src->params;
577 foreach(SearchParameters::$serializedFields as $field)
579 $this->$field = $src->$field;
587 $this->params = array();
589 $this->handlers = array();
601 function get($field, $mode =
null)
603 if (!isset($this->params[$field]))
return null;
605 $val = $this->params[$field];
606 if ($val->mode ==
"range")
612 else if ($mode ==
"to")
620 if ($mode !==
null && $val->mode != $mode)
return null;
623 $value = $val->value;
624 trace(
"SearchParameters::get({$field}:$mode): $value", 3);
642 $this->paramHandlers[$field] = $handler;
643 if (!$this->target->hasField($field))
645 $this->additional[] = $field;
652 $this->isDefaultState =
true;
654 $fields = array_keys($this->target->getFields());
655 foreach($array as $field => $value)
657 list($fieldname, $mode) = explode(
":", $field);
661 if ($this->target->filter && $this->target->filter->isExcluded($fieldname))
663 trace(
"## Skipping $fieldname", 4);
667 if (!$this->target->hasField($fieldname) &&
668 (!$this->form || !$this->form->hasAdditional($fieldname)))
670 trace(
"### Skipping $fieldname", 4);
674 $this->isDefaultState =
false;
678 $this->empty =
false;
680 $this->
setParam($fieldname, $mode, $value);
691 if (is_array($value)) $value = implode(
",", array_values($value));
693 if (isset($this->params[$fieldname]))
695 $p = $this->params[$fieldname];
698 if ($mode ==
"from" && $p->mode ==
"to")
705 else if ($mode ==
"to" && $p->mode ==
"from")
709 $p->from = $p->value;
735 foreach($this->params as $name => $value)
737 list($f, $mode) = explode(
":", $name);
738 if ($f == $field) unset($this->params[
"$f:$mode"]);
742 function set($field, $mode, $value)
744 $this->
setParam($field, $mode, $value);
759 foreach($this->params as $key => $value)
761 list($field, $mode) = explode(
":", $key);
764 $this->params[
"$new:$mode"] = $value;
765 unset($this->params[
"$old:$mode"]);
772 $this->params[$new] = $this->params[$old];
788 for($i = 1; $i < func_num_args(); ++$i)
798 foreach($this->params as $name => $value)
800 if ($value ==
"")
continue;
802 $qs .= ($qs ==
"") ?
"?" :
"&";
804 $qs .= urlencode($name);
806 $qs .= urlencode($value);
824 trace(print_r($this->params,
true), 3);
826 foreach($this->params as $field => $param)
828 $joinWith = (!$first) ? $this->joinWith :
"";
830 $modifier = $param->mode;
831 $value = $param->value;
844 if(!array_key_exists($field, $this->paramHandlers))
846 $fields = $this->target->getFields();
847 $handler = $this->handlers[$fields[$field]];
851 $clause = $this->
getClause($handler, $modifier, $field, $value);
855 $handler = $this->paramHandlers[$field];
857 if(is_callable($handler))
858 $clause = call_user_func($handler, $field, $value);
859 elseif(method_exists($handler, $modifier))
860 $clause = $handler->$modifier($field, $value);
875 $clause[] = $this->
_getClause($handler, $modifier, $field, $value);
881 foreach($secondaries as $secondary)
883 $clause[] = $this->
_getClause($handler, $modifier, $secondary, $value);
886 return "(".implode(
" OR ", $clause).
") ";
902 $clause = $handler->equal($field, $value);
907 $clause = $handler->like($field, $value);
912 $clause = $handler->startsWith($field, $value);
917 if (array_key_exists(
"{$field}:to", $this->params))
919 trace(
"date range", 3);
923 $clause = $handler->from($field, $value);
929 $clause = $handler->to($field, $value);
934 $param = $this->params[$field];
935 $clause = $handler->range($field, $param->from, $param->to);
940 $clause = $handler->member($field, $value);
945 $clause = $handler->any($field, $value);
950 $clause = $handler->all($field, $value);
955 $clause = $handler->fullName($field, $value);
960 $clause = $handler->checked($field, $value);
989 $constraint =
"{$firstText} $clause";
994 $constraint .=
" $joinWith $clause";
1009 if($constraint ==
"")
return;
1011 if(strpos($firstText,
"(") !==
false)
1013 $constraint .=
") ";
1082 "all" =>
"match all words in any order",
1083 "any" =>
"match any words");
1095 $this->modifiers = array();
1099 $this->validator->id = $this->id;
1109 for($i = 1; $i < count(
$fields); ++$i)
1111 $this->modifiers[
$fields[$i]] = $mode;
1123 $mode = (array_key_exists($field, $this->modifiers)) ? $this->modifiers[$field] :
"equal";
1132 $this->params->fromGET();
1140 $this->params->fromPOST();
1145 $this->params->fromArray($_REQUEST);
1158 $this->params->paramHandlers[$field] = $handler;
1171 $obj =& $this->data;
1173 foreach(array_keys($obj->getFields()) as $field)
1175 trace(
"SearchForm writeScript field $field", 3);
1177 !($obj->filter && $obj->filter->isExcluded($field)))
1184 $renderer->renderSearchScript($field, $mode);
1190 foreach($this->additional as $r)
1192 $renderer = $r[
'renderer'];
1193 $field = $r[
'field'];
1195 $field = $renderer->field;
1198 $renderer->renderSearchScript($field, $mode);
1201 echo
"<script type='text/javascript'>\n";
1202 echo $this->validator->writeScript();
1204 echo
"function onSubmit{$this->id}(form)\n{\n";
1206 echo
"\tif (validate_{$this->id} != null && !validate_{$this->id}(form)) return false;\n";
1209 foreach(array_keys($this->fields) as $field)
1211 if ($field != $pk && !($filter && $filter->isExcluded($field)))
1216 $renderer->renderOnSubmitHandler($field);
1221 foreach($this->additional as $r)
1223 $r[
'renderer']->renderOnSubmitHandler($r[
'field']);
1226 if ($this->onSubmitHandler)
1228 echo
"\t if (!{$this->onSubmitHandler}(form)) return false;\n;";
1231 if ($this->interstitialMessage)
1233 echo
"\tinterstitial('".jsSafe($this->interstitialMessage).
"');\n;";
1236 echo
"\treturn true;\n}\n\n";
1239 echo
"\twindow.addEvent('domready', function() {\n";
1241 if ($this->allowPartialSave)
1243 $managerOptions =
"{partialSaveContainer: '{$this->partialSaveContainerID}', partialSaveLabel: '{$this->partialSaveLabel}'}";
1247 $managerOptions =
"{}";
1250 echo
"\tnew AutoFormManager('{$this->id}', {$managerOptions});\n";
1255 $script = ob_get_contents();
1269 $filter = $this->data->getFilter();
1271 foreach(array_keys($this->fields) as $field)
1273 if ($filter && $filter->isExcluded($field))
continue;
1274 if ($this->
readonly[$field])
continue;
1282 $renderer->addSearchValidatorsToForm($field, $mode,
$required);
1286 foreach($this->additional as $r)
1289 $required = (array_search($r[
'field'], $this->
required) === FALSE) ?
false :
true;
1291 $r[
'renderer']->addSearchValidatorsToForm($r[
'field'], $mode,
$required);
1308 foreach($this->validator->validators as $v)
1310 if($v->field != $field)
continue;
1311 if($mode !=
"range")
1313 $v->field =
"{$v->field}:{$mode}";
1317 $v->field =
"{$v->field}:from";
1318 $toLabel = preg_replace(
"/between|to/i",
"To", $v->title);
1320 $this->validator->add($toV);
1334 $obj =& $this->data;
1335 $pk = $obj->primary_key;
1337 if ($this->preserveQueryString)
1339 $obj->fromREQUEST();
1345 $submitLabel =
"Search ".pluralize($obj->prettifyClassName(
true));
1348 if (!$this->subordinate)
1350 echo
"<form id='{$this->id}' method='{$this->method}' action='{$this->action}' enctype='multipart/form-data'";
1351 if (!$this->ajaxSubmitHandler) echo
" onsubmit='return onSubmit{$this->id}(this);'";
1357 echo
"<input type='hidden' name='#FORMID#' value='{$this->id}'/>";
1360 foreach(array_keys($this->hidden) as
$hidden)
1362 echo
"<input id='{$hidden}' type='hidden' name='$hidden' value='".htmlSafe($obj->get(
$hidden)).
"'/>\n";
1365 if ($this->preserveQueryString)
1367 foreach($_GET as $key => $value)
1369 if ($key ==
"identifier" || $key ==
"section" || $key ==
"submit" || array_key_exists($this->hidden, $key) || $obj->hasField($key))
continue;
1370 echo
"<input id='{$this->id}_{$key}' type='hidden' name='$key' value='".htmlSafe($value).
"'/>\n";
1375 $this->layout->startUngrouped();
1377 if ($this->buttons_at_top && !$this->subordinate)
1379 $this->layout->startButtonLine();
1385 $this->layout->endButtonLine();
1388 $this->layout->errorBox();
1390 if ($this->markRequiredFields && $this->validator->hasRequiredFields())
1392 $this->layout->requiredFields($this->requiredFieldsText);
1397 if (!$this->subordinate)
1399 $this->layout->startButtonLine();
1404 $this->layout->endButtonLine();
1407 $this->layout->endUngrouped();
1409 if (!$this->subordinate)
1417 $obj =& $this->data;
1418 $filter = $obj->getFilter();
1420 if (count($this->groups) > 0)
1422 $this->layout->endUngrouped();
1424 foreach($this->groups as $legend =>
$fields)
1426 $collapsible = array_key_exists($legend, $this->collapsibleGroups);
1429 $cf = $this->collapsibleGroups[$legend];
1430 $collapsed = !$this->data->$cf;
1433 $this->layout->startGroup($legend, $collapsible, $collapsed);
1437 if ($field != $pk && !array_key_exists($field, $this->hidden) && !array_key_exists($field, $this->renderedFields) &&
1438 ($this->
hasAdditional($field) || !($filter && $filter->isExcluded($field))))
1444 $this->layout->endGroup();
1447 $this->layout->startUngrouped();
1451 foreach(array_keys($this->fields) as $field)
1453 if ($field != $pk && !array_key_exists($field, $this->hidden) && !array_key_exists($field, $this->renderedFields) &&
1454 ($this->
hasAdditional($field) || !($filter && $filter->isExcluded($field))))
1460 foreach($this->additional as $r)
1462 $renderer = $r[
'renderer'];
1463 $field = $r[
'field'];
1465 $field = $renderer->field;
1467 trace(
"Rendering additional field $field", 3);
1469 if (!array_key_exists($field, $this->renderedFields))
1487 if(!$renderer && !$this->data->hasField($field) && $this->data->getType($field) !=
"Timestamp")
1489 foreach($this->additional as $r)
1491 $renderer = $r[
'renderer'];
1492 $field = $r[
'field'];
1494 $field = $renderer->field;
1500 if(!$this->readOnlyForm)
1502 $renderer->renderSearchField($field, $mode);
1504 else if($this->readOnlyForm && (get_class($renderer) !=
DateFieldRenderer || $mode !=
"range"))
1506 $value = $this->params->get($field, $mode);
1511 $this->data->set($field, $value);
1512 $renderer->renderReadOnly($field);
1513 $this->hasSearchCriteria =
true;
1516 else if($this->readOnlyForm)
1518 $date_from = $this->params->get($field,
"from");
1519 $date_to = $this->params->get($field,
"to");
1520 if($date_from || $date_to)
1522 $renderer->renderDateRangeReadOnly($field, $date_from, $date_to);
1523 $this->hasSearchCriteria =
true;
1528 $this->renderedFields[$field] =
true;
1534 foreach($this->additional as $r)
1536 $renderer = $r[
'renderer'];
1537 $field = $r[
'field'];
1539 $field = $renderer->field;
1543 if(!array_key_exists($field, $this->renderedFields))
1545 $renderer->renderSearchField($field, $mode);
1547 $this->renderedFields[$field] =
true;
1558 if ($this->formCSS) echo
" class='{$this->formCSS}'";
1559 if ($this->style) echo
" style='{$this->style}'";
1562 $obj =& $this->data;
1563 $pk = $obj->primary_key;
1564 $filter = $obj->getFilter();
1566 foreach($this->params->params as $param => $value)
1568 list($field, $modifier) = explode(
":", $param);
1569 if(!array_key_exists($field, $this->modifiers))
1573 if (count($this->groups) > 0)
1575 foreach($this->groups as $legend =>
$fields)
1579 if ($field != $pk && !array_key_exists($field, $this->hidden) &&
1580 !array_key_exists($field, $this->renderedFields) &&
1581 !($filter && $filter->isExcluded($field)))
1589 foreach(array_keys($this->fields) as $field)
1591 if ($field != $pk && !array_key_exists($field, $this->hidden) && !array_key_exists($field, $this->renderedFields) && !($filter && $filter->isExcluded($field)))
1597 foreach($this->additional as $r)
1599 $renderer = $r[
'renderer'];
1600 $field = $r[
'field'];
1602 $field = $renderer->field;
1603 if (!array_key_exists($field, $this->renderedFields) && !($filter && $filter->isExcluded($field)))
1609 if(!$this->hasSearchCriteria)
1611 echo
"<tr>\n<td style='padding-top: 10px; padding-bottom: 10px'><i>{$this->emptyMessage}</i></td>\n</tr>\n";
1620 echo
"<tr><td>". preg_replace(
"/^( )+/",
"",
$buttons) .
"</td>\n<tr>\n";
equal($name, $value)
Generates the constraint expression for equality matching parameters.
checked($name, $value)
Generate the constraint expresssion for matching boolean only when the UI element is selected.
static quote($str)
Quote a string value based on the character set of the global connection.
static escape($str)
Escapes a string based on the character set of the global connection.
member($name, $set)
Generate the constraint expression for set membership matching paramters, matching values in a comma ...
__construct($class, $xref, $foreignKey)
Field renderer for date data fields.
DateSearchParameterHandler is a SearchParameterHandler for date database types.
equal($name, $value)
Generates the constraint expression for equality matching parameters.
range($name, $from, $to)
Generates the constraint expression for 'range' matching parameters, i.e.
to($name, $to)
Generates the constraint expression for 'to' matching parameters, i.e.
startsWith($name, $value)
Generates the constraint expression for 'startsWith' matching parameters, i.e.
like($name, $value)
Generates the constraint expression for 'like' matching parameters, i.e.
from($name, $from)
Generates the constraint expression for 'from' matching parameters, i.e.
NumberSearchParameterHandler is a SearchParameterHandler for numeric database types.
from($name, $from)
Generates the constraint expression for 'from' matching parameters, i.e.
member($name, $set)
Generate the constraint expression for set membership matching paramters, matching values in a comma ...
to($name, $to)
Generates the constraint expression for 'to' matching parameters, i.e.
range($name, $from, $to)
Generates the constraint expression for 'range' matching parameters, i.e.
startsWith($name, $value)
Generates the constraint expression for 'startsWith' matching parameters, i.e.
any($name, $value)
Generate the constraint expression for matching any word in a group of words.
equal($name, $value)
Generates the constraint expression for equality matching parameters.
like($name, $value)
Generates the constraint expression for 'like' matching parameters, i.e.
Base class for SearchParameterHandlers.
member($name, $set)
Generate the constraint expression for set membership matching paramters, matching values in a comma ...
any($name, $value)
Generate the constraint expression for matching any word in a group of words.
to($name, $to)
Generates the constraint expression for 'to' matching parameters, i.e.
startsWith($name, $value)
Generates the constraint expression for 'startsWith' matching parameters, i.e.
from($name, $from)
Generates the constraint expression for 'from' matching parameters, i.e.
range($name, $from, $to)
Generates the constraint expression for 'range' matching parameters, i.e.
like($name, $value)
Generates the constraint expression for 'like' matching parameters, i.e.
equal($name, $value)
Generates the constraint expression for equality matching parameters.
all($name, $value)
Generate the constraint expression for matching all words in a group of words but allowing other word...
checked($name, $value)
Generate the constraint expresssion for matching boolean only when the UI element is selected.
fullName($f_name, $l_name, $value)
Generate the constraint expression for matching the f_name and l_name fields to a given value.
__construct($mode, $value)
The SearchParameters class interprets the set of input parameters for a search and generates the corr...
$empty
true if no search parameters were specified, false if any parameter was found
SearchParameters($target, $form=null)
setParam($fieldname, $mode, $value)
static closeClause(&$constraint, $firstText)
clearParam($field)
Clear any parameters set for the specified field.
_getClause($handler, $modifier, $field, $value)
generateConstraint($first=true, $firstText="WHERE")
generateConstraint
static joinClauses(&$first, $clause, $joinWith="AND", $firstText)
joinClauses
getClause($handler, $modifier, $field, $value)
setHandler($field, $handler)
Override default handling by setting a custom callback to generate the constraint for a field.
secondaryFields($src)
Specifies additional data fields to search when querying for the given source field.
StringSearchParameterHandler is a SearchParameterHandler for text database types.
equal($name, $value)
Generates the constraint expression for equality matching parameters.
from($name, $from)
Generates the constraint expression for 'from' matching parameters, i.e.
range($name, $from, $to)
Generates the constraint expression for 'range' matching parameters, i.e.
any($name, $value)
Generate the constraint expression for matching any word in a group of words.
startsWith($name, $value)
Generates the constraint expression for 'startsWith' matching parameters, i.e.
like($name, $value)
Generates the constraint expression for 'like' matching parameters, i.e.
to($name, $to)
Generates the constraint expression for 'to' matching parameters, i.e.
member($name, $set)
Generate the constraint expression for set membership matching paramters, matching values in a comma ...
all($name, $value)
Generate the constraint expression for matching all words in a group of words but allowing other word...
fullName($f_name, $l_name, $value)
Generate the constraint expression for matching the f_name and l_name fields to a given value.
The ValidationEngine takes an array of validator objects in its constructor, and is then able to gene...
checkNumeric($p)
Security helper function.
trace($msg, $lvl=3, $callStack=null)
Send output to the trace log.