Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/joomla5/plugins/fabrik_form/upsert/ |
| [Home] [System Details] [Kill Me] |
<?php
/**
* Update / insert a database record into any table
*
* @package Joomla.Plugin
* @subpackage Fabrik.form.upsert
* @copyright Copyright (C) 2005-2020 Media A-Team, Inc. - All rights
reserved.
* @license GNU/GPL http://www.gnu.org/copyleft/gpl.html
*/
// No direct access
defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Fabrik\Helpers\Php;
// Require the abstract plugin class
require_once COM_FABRIK_FRONTEND . '/models/plugin-form.php';
/**
* Update / insert a database record into any table
*
* @package Joomla.Plugin
* @subpackage Fabrik.form.upsert
* @since 3.0.7
*/
class PlgFabrik_FormUpsert extends PlgFabrik_Form
{
/**
* Database driver
*
* @var JDatabaseDriver
*/
protected $upsertDb = null;
/**
* process the plugin, called after form is submitted
*
* @return bool
*/
public function onAfterProcess()
{
$params = $this->getParams();
$w = new FabrikWorker;
$formModel = $this->getModel();
// @FIXME to use selected connection
$upsertDb = $this->getDb();
$query = $upsertDb->getQuery(true);
$this->data = $this->getProcessData();
if (!$this->shouldProcess('upsert_conditon', null, $params))
{
return;
}
$table = $this->getTableName();
$pk =
FabrikString::safeColName($params->get('primary_key'));
$rowId = $params->get('row_value', '');
// Used for updating previously added records. Need previous pk val to
ensure new records are still created.
$origData = $formModel->getOrigData();
$origData = FArrayHelper::getValue($origData, 0, new stdClass);
if (isset($origData->__pk_val))
{
$this->data['origid'] = $origData->__pk_val;
}
$rowId = $w->parseMessageForPlaceholder($rowId, $this->data,
false);
$upsertRowExists = $this->upsertRowExists($table, $pk, $rowId);
/**
* If row exists and "insert only", or row doesn't exist
and "update only", bail out
*/
if (
($upsertRowExists &&
$params->get('upsert_insert_only', '0') ===
'1')
||
(!$upsertRowExists &&
$params->get('upsert_insert_only', '0') ===
'2')
)
{
return true;
}
$fields = $this->upsertData($upsertRowExists);
// make sure we have at least one field to upsert
if (empty($fields))
{
return true;
}
$query->set($fields);
if ($rowId === '')
{
$query->insert($table);
}
else
{
if ($upsertRowExists)
{
$query->update($table)->where($pk . ' = ' .
$upsertDb->quote($rowId));
}
else
{
$query->insert($table);
}
}
$upsertDb->setQuery($query);
$upsertDb->execute();
return true;
}
/**
* Get db
*
* @return JDatabaseDriver
*/
protected function getDb()
{
if (!isset($this->upsert_db))
{
$params = $this->getParams();
$cid = $params->get('connection_id');
$connectionModel =
BaseDatabaseModel::getInstance('connection',
'FabrikFEModel');
$connectionModel->setId($cid);
$this->upsert_db = $connectionModel->getDb();
}
return $this->upsert_db;
}
/**
* Get fields to update/insert
*
* @param bool $upsertRowExists
*
* @return array
*/
protected function upsertData($upsertRowExists = false)
{
$params = $this->getParams();
$w = new FabrikWorker;
$upsertDb = $this->getDb();
$upsert = json_decode($params->get('upsert_fields'));
$fields = array();
/** @var FabrikFEModelForm $formModel */
$formModel = $this->getModel();
if ($formModel->isNewRecord() || !$upsertRowExists)
{
if ($params->get('upsert_pk_or_fk', 'pk') ==
'fk')
{
$row_value = $params->get('row_value', '');
if ($row_value == '{origid}')
{
$fk =
FabrikString::safeColName($params->get('primary_key'));
$rowId = $formModel->getInsertId();
$fields[] = $fk . ' = ' . $upsertDb->q($rowId);
}
}
}
for ($i = 0; $i < count($upsert->upsert_key); $i++)
{
$k = FabrikString::shortColName($upsert->upsert_key[$i]);
$k = $upsertDb->qn($k);
$v = $upsert->upsert_value[$i];
$v = $w->parseMessageForPlaceholder($v, $this->data);
if ($upsert->upsert_eval_value[$i] === '1')
{
FabrikWorker::clearEval();
$res = Php::Eval(['code' => $v,
'vars'=>['formModel'=>$formModel]]);
FabrikWorker::logEval($res, 'Eval exception : upsert : ' . $v
. ' : %s');
// if the eval'ed code returned false, skip this
if ($res === false)
{
continue;
}
$v = $res;
}
if ($v == '')
{
$v = $w->parseMessageForPlaceholder($upsert->upsert_default[$i],
$this->data);
}
/*
* $$$ hugh - permit the use of expressions, by putting the value in
parens, with option use
* of double :: to provide a default for new row (rowid is empty). This
default is seperate from
* the simple default used above, which is predicated on value being
empty. So simple usage
* might be ..
*
* (counter+1::0)
*
* ... if you want to increment a 'counter' field. Or you
might use a subquery, like ...
*
* ((SELECT foo FROM other_table WHERE fk_id = {rowid})::'foo
default')
*/
if (!preg_match('#^\((.*)\)$#', $v))
{
$v = $upsertDb->q($v);
}
else
{
$matches = array();
preg_match('#^\((.*)\)$#', $v, $matches);
$v = $matches[1];
$v = explode('::', $v);
if (count($v) == 1)
{
$v = $v[0];
}
else
{
if ($formModel->isNewRecord())
{
$v = $v[1];
}
else
{
$v = $v[0];
}
}
}
$fields[] = $k . ' = ' . $v;
}
return $fields;
}
/**
* Get the table name to insert / update to
*
* @return string
*/
protected function getTableName()
{
$params = $this->getParams();
$listId = $params->get('table');
$listModel = BaseDatabaseModel::getInstance('list',
'FabrikFEModel');
$listModel->setId($listId);
return $listModel->getTable()->db_table_name;
}
/**
* See if row exists on upsert table
* @param string $table Table name
* @param string $field
* @param string $value
*
* @return bool
*/
protected function upsertRowExists($table, $field, $value)
{
$params = $this->getParams();
$cid = $params->get('connection_id');
$connectionModel = BaseDatabaseModel::getInstance('connection',
'FabrikFEModel');
$connectionModel->setId($cid);
$db = $connectionModel->getDb();
$query = $db->getQuery(true);
$query->select('COUNT(*) AS
total')->from($table)->where($field . ' = ' .
$db->q($value));
$db->setQuery($query);
return (int) $db->loadResult() > 0;
}
}