Predefined actions, filter, checks and JS Events
Actions, checks and filter work as a callback function when specific events occur. This way you can add functionality to bpfw events without changing the bpfw code.
Actions just notify you, while filter provide a value that is expected to be returned in a manipulated form.
Like an array of allowed values.
A check requires you to return true or the linked action will be canceled.
Hint: You can define you own filters and actions, for that take a look at https://bpfw.org/default-functions -> “commonFunctions.inc.php and other core files”.
Filters:
FILTER_FORMFIELD_VALIDATION
// You can use it to do more complex form validations.
// If not empty, the errors in errorsAlreadyFound will be shown in the dialog and submit will not be possible.
// Example:
class testModel{
function __construct(){
// [..]
bpfw_add_filter(FILTER_FORMFIELD_VALIDATION, $this->GetTableName(), array($this, "validateForm"), 10, 8);
}
function validateForm($errorsAlreadyFound, $type, $value, $headerValue, $formValues, $key, $model, $component)
{
$firstname = $formValues["firstname"]->data;
if($firstname == "Balrog"){
$errorsAlreadyFound[] = "You shall not pass";
}
}
}
FILTER_ENTRY_SELECT_WHERE / FILTER_ENTRY_SELECT_JOIN / DbModel::FILTER_GET_DBMODEL
// Manipulates the select queries of the model.
// can be used to restrict access, add tables for calculated fields and a lot more
// Example:
class testModel{
function __construct(){
// [..]
// manipulates the join
bpfw_add_filter(parent::FILTER_ENTRY_SELECT_WHERE, $this->GetTableName(), array($this, "filterSelectEntriesWherecust"), 10, 5);
// manipulates the where
bpfw_add_filter(parent::FILTER_ENTRY_SELECT_JOIN, $this->GetTableName(), array($this, "filterSelectEntriesJoin"), 10, 5);
// manipulates the database fields selected
bpfw_add_filter(DbModel::FILTER_EXTRAFIELDS, $this->GetTableName(), array($this, "extrafieldsForModel"), 10, 3);
}
function filterSelectEntriesWherecust($where, $count, $offset, $sort, $join)
{
// non admin users only have access to "their" data
if (!bpfw_isAdmin()) {
$limitToUserid = bpfw_getUserId();
$where = "(" . $where . ")" . " AND ce.userId = '$limitToUserid'";
}
return $where;
}
function filterSelectEntriesJoin($join, $where, $count, $offset, $sort): string
{
return $join .= " left join test2 on test2.testId = test.testId ";
}
function extrafieldsForModel($extraFields, $model, $tablename){
$extraFields["test2_field"]="test2.sometimefield";
return $extraFields;
}
protected function loadDbModel(): array
{
// [..]
$this->addForeignFieldAsLabel( "test2_field", "Field from test2", "timestamp", array( FORMSETTING::PAGE=>TcggradingModel::PAGE_INFO, LISTSETTING::HIDDENONLIST=>false, FORMSETTING::HIDDENONEDIT=>true, FORMSETTING::HIDDENONADD=>true, LISTSETTING::AJAX_SORTABLE=>true ) );
}
}
DbModel::FILTER_GET_DBMODEL
// filter the db fields of a model. Manipulate default Models without cloning their source or add conditional fields.
// Example (can be used in your functions.inc.php):
bpfw_add_filter(DbModel::FILTER_GET_DBMODEL, "functions_inc_php", "dbmodel_filter", 10, 3);
function dbmodel_filter($dbfields, $model, $tablename){
if($tablename == "test" || $tablename == "test2"){
$model->addCheckbox("added_checkbox", "checked", array(VIEWSETTING::DEFAULTVALUE=>"0", FORMSETTING::PAGE=>1,LISTSETTING::HIDDENONLIST=>true, FORMSETTING::HIDDENONADD=>true, FORMSETTING::HIDDENONEDIT=>false, FORMSETTING::POSITION=>POSITION_RIGHT));
}
return $dbfields;
}
FILTER_LANGUAGELIST
// add possibility to add custom languages like german sie and du
// Example:
bpfw_add_filter(FILTER_LANGUAGELIST, "functions_inc_php", "addCustomLanguages", 10, 1);
function addCustomLanguages($list){
$list["kl"] = "Klingon";
$list["de_du"] = "Deutsch (Du)";
return $list";
}
Actions used in the Views:
ACTION_DEFAULTLISTVIEW_DISPLAY_BUTTONS
ACTION_DEFAULTLISTVIEW_BEFORE_RENDER_BUTTONS
ACTION_EDITDIALOG_BEFORE_HEADER_CLOSE_ICON
ACTION_DEFAULTLISTVIEW_BEFORE_RENDER_TABLE
// Manipulates the select queries of the model.
// can be used to restrict access, add tables for calculated fields and a lot more
// Example:
class testView{
function initializeVariables(){
/* $this->makeArrow = !$this->print;
$this->makeDetail = !$this->print && bpfw_isAdmin();
$this->hasAnyButtons = $this->makeDetail || $this->makeEdit || $this->makeTrash || $this->makeDuplicate || $this->makeArrow || $this->makeSendPassword; */
// add buttons to context menu
bpfw_add_action(DefaultlistView::ACTION_DEFAULTLISTVIEW_DISPLAY_BUTTONS, $this->model->GetTableName(), array($this, "extraButtons"), 10, 2 );
// in dialog before close button, add pdfmailer or other icons here
bpfw_add_action(DefaultlistView::ACTION_EDITDIALOG_BEFORE_HEADER_CLOSE_ICON, $this->model->GetTableName(), array($this, "actionBeforeCloseIcon"), 10, 1);
// shown in main view before the table. Best location for custom content before the List
bpfw_add_action(DefaultlistView::ACTION_DEFAULTLISTVIEW_BEFORE_RENDER_TABLE, $this->model->GetTableName(), array($this, "createBackupBar"));
// before top buttons of the view (add new entry, print etc) are rendered
bpfw_add_action(DefaultlistView::ACTION_DEFAULTLISTVIEW_BEFORE_RENDER_BUTTONS, $this->model->GetTableName(), array($this, "doBeforeTopButtons") );
parent::initializeVariables();
}
function actionBeforeCloseIcon($rowId): void
{
if (bpfw_isAdmin()) {
?>
<span class="headerdialogbuttonrow datalist_button_wrapper list-enabled">
<button type="button" class="tableicon_size open_eventmanager"
onclick="startIFrameDialog(<?php echo $rowId; ?>, '?p=examplepdfmanager&modelused=examplecomplex&hideNavigation=true&filter=<?php echo $rowId; ?>');"
data-id="<?php echo $rowId; ?>">
<i class="tableicon_small fas fa-file-pdf"> Create .pdf</i>
</button>
<button type="button" class="tableicon_size open_attachments"
onclick="startIFrameDialog(<?php echo $rowId; ?>, '?p=exampleattachments&hideNavigation=true&filter=<?php echo $rowId; ?>');"
data-id="<?php echo $rowId; ?>">
<i class="tableicon_small fa fa-paperclip"> Attachments</i>
</button>
</span>
<?php
}
}
// add buttons to the contextmenu
function extraButtons($key, $value){
echo '
<a class="tableicon_size open_eventmanager iframepopup" data-id='.$key.' title="Lebenslauf drucken" href="?p=usermanager&hideNavigation=true&filter=' . $key . '">
<i class="tableicon fa fa-print"></i>
</a>';
}
function createBackupBar($key = "all", $value = "?")
{
echo '
<a target="_blank" title="export as JSON" class="tableicon_size" href="?p=backup&ajaxCall=true&command=createBackupFull">
<i class="tableicon fa fa-hdd">'.__("Create new backup").'</i>
</a>';
echo '
<a target="_blank" title="export as JSON" class="tableicon_size" href="?p=backup&ajaxCall=true&command=createBackupPartial">
<i class="tableicon fa fa-hdd">'.__("New partial backup (Database only)").'</i>
</a>';
}
}
Checks
(checks are like filters, but all corresponding check must return true for the do_check to succeed)
ACTION_DEFAULTLISTVIEW_DISPLAY_ENTRY
// only if true is returned, the row will be displayed
// Example:
class testView{
function initializeVariables(){
bpfw_add_check(DefaultlistView::ACTION_DEFAULTLISTVIEW_DISPLAY_ENTRY, $this->model->GetTableName(), array($this, "statusFilter"));
parent::initializeVariables();
}
function statusFilter($value){
if(!isset($this->statusFilter[$value->status])){
return false;
}
return true;
}
}
Javascript Events
startEdit / startDuplicate -> called when an edit or update dialog is opened
EditEntrySubmit AddEntrySubmit deleteEntry
-> called on adding/deleting/editing a new Entry. Can be used to preprocess (calculated) fields before submitting.
startIframeDialog – called when a new IFrame based dialog is opened – like pdf creation
//register three different events that calculate new prices
registerBpfwEvent("AddEntrySubmit EditEntrySubmit deleteEntry", function (params) {
if (params.model === "orderproduct") {
if (params.event === "deleteEntry") {
recalcOrderPrices("#" + getIdOfCurrentDialog());
} else {
recalcOrderPrices("#" + getIdOfParentDialog());
}
}
});
// reinit selectpicker on start edit
registerBpfwEvent("startEdit", function (params) {
if(params.model === "appsettings") {
// component initializer of called form is not always including selectpicker, so fire again manually
jQuery(".selectpicker").selectpicker("refresh");
}
});