File "model.php"
Full Path: /home/romayxjt/public_html/wp-content/plugins/vikbooking/admin/helpers/src/mvc/model.php
File size: 9.73 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* @package VikBooking
* @subpackage core
* @author E4J s.r.l.
* @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
* @link https://vikwp.com
*/
// No direct access
defined('ABSPATH') or die('No script kiddies please!');
/**
* VikBooking MVC base model declaration.
*
* @since 1.5.10
*/
abstract class VBOMvcModel extends JObject
{
/**
* Cached used to store the supported columns of the requested database tables.
*
* @var string
*/
protected static $fields = [];
/**
* The database table name.
*
* @var string
*/
protected $tableName = null;
/**
* The database table primary key name.
*
* @var string
*/
protected $tableKeyName = 'id';
/**
* Returns a new instance of the requested model.
*
* @param string $name The model name.
* @param array $options The model configuration.
*
* @return VBOMvcModel
*/
public static function getInstance($name, array $options = [])
{
/**
* Trigger hook to allow third party plugins to extend the default models in VikBooking without
* altering a single line of code from the core of the plugin.
*
* It is either possible to swap the name or to return a new instance of VBOMvcModel.
*
* @param string &$name A reference to the requested model.
* @param array &$options A reference to the model configuration.
*
* @return mixed
*/
$results = VBOFactory::getPlatform()->getDispatcher()->filter('onBeforeCreateModelVikBooking', [&$name, &$options]);
// filter the returned values to take only the first valid instance
$results = array_filter($results, function($data)
{
return $data instanceof VBOMvcModel;
});
if ($results)
{
// class returned by a plugin, directly use it
return $results[0];
}
// fallback to the default classes in VikBooking
$suffix = str_replace('_', ' ', $name);
$suffix = str_replace(' ', '', ucwords($suffix));
$modelClass = 'VBOModel' . $suffix;
if (!class_exists($modelClass))
{
throw new Exception(sprintf('Model [%s] not found', $name), 404);
}
return new $modelClass($options);
}
/**
* Returns the model name.
*
* @return string
*/
public function getName()
{
if (preg_match("/^VBOModel([a-z0-9_]+)$/i", get_class($this), $match))
{
return strtolower($match[1]);
}
// unable to extract model name from class, use the file name
return basename(__FILE__, '.php');
}
/**
* Basic item loading implementation.
*
* @param mixed $pk An optional primary key value to load the row by, or an array of fields to match.
* If not set the instance property value is used.
*
* @return mixed The record object on success, null otherwise.
*/
public function getItem($pk)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn($this->tableName));
if (is_array($pk))
{
foreach ($pk as $column => $value)
{
$query->where($db->qn($column) . ' = ' . $db->q($value));
}
}
else
{
$query->where($db->qn($this->tableKeyName) . ' = ' . (int) $pk);
}
$db->setQuery($query, 0, 1);
return $db->loadObject();
}
/**
* Method to save the form data.
*
* @param mixed $data The form data.
*
* @return mixed The primary key of the saved item, false otherwise.
*/
public function save($data)
{
$data = (array) $data;
// let the children bind the data array before save
if (!$this->preflight($data))
{
return false;
}
// check if we have an empty record
$isNew = empty($data[$this->tableKeyName]);
// store the object within the database
$pk = $this->store((array) $data);
if (!$pk)
{
return false;
}
// let the children perform extra actions after saving
$this->postflight((array) $data, $isNew);
return $pk;
}
/**
* Method to delete one or more records.
*
* @param mixed $pks An array of record primary keys.
*
* @return boolean True if successful, false if an error occurs.
*/
public function delete($pks)
{
if (!$pks)
{
// nothing to delete
return false;
}
if (!is_array($pks))
{
// wrap in an array
$pks = [$pks];
}
$app = JFactory::getApplication();
$affected = true;
foreach ($pks as $pk)
{
// fetch item details
$item = $this->getItem($pk);
if (!$item)
{
continue;
}
/**
* Runs before deleting the given data.
* It is possible to validate here whether the item should be deleted or not.
*
* @param object $data The record to delete.
* @param self $model The current model.
*
* @return boolean False to abort the deleting process.
*
* @since 1.5.10
*/
$results = $app->triggerEvent('onBeforeDeleteVikBooking' . ucfirst($this->getName()), [$item, $this]);
// check whether a plugin aborted the deleting process
if (in_array(false, $results, true))
{
continue;
}
// remove item
$result = $this->remove($item);
/**
* Runs after deleting the given data.
* It is possible to perform here some extra actions.
*
* @param object $data The deleted item.
* @param boolean $success True in case of success, false otherwise.
* @param self $model The current model.
*
* @return void
*
* @since 1.5.10
*/
$app->triggerEvent('onAfterDeleteVikBooking' . ucfirst($this->getName()), [$item, $result, $this]);
$affected = $affected || $result;
}
return $affected;
}
/**
* Runs before saving the given data.
* It is possible to inject here additional properties to save.
*
* @param array &$data A reference to the data to save.
*
* @return boolean True on success, false otherwise.
*/
protected function preflight(array &$data)
{
$app = JFactory::getApplication();
/**
* Runs before saving the given data.
* It is possible to inject here additional properties to save.
*
* @param array &$data A reference to the data to save.
* @param self $model The current model.
*
* @return boolean False to abort the saving process.
*
* @since 1.5.10
*/
$results = $app->triggerEvent('onBeforeSaveVikBooking' . ucfirst($this->getName()), [&$data, $this]);
// check whether a plugin aborted the saving process
if (in_array(false, $results, true))
{
return false;
}
return true;
}
/**
* Converts the array data into an object compatible with the database
* structure of the specified table.
*
* @param array $data The requested data.
*
* @return object The object ready to be saved.
*/
protected function prepareSaveData(array $data)
{
$table = new stdClass;
// bind only the columns supported by the database table
foreach ($this->getTableColumns() as $field => $type)
{
if (isset($data[$field]))
{
// always encode in JSON format non-scalar values
if (!is_scalar($data[$field]))
{
$data[$field] = json_encode($data[$field]);
}
$table->{$field} = $data[$field];
}
}
return $table;
}
/**
* Saves the specified data into the database.
*
* @param array $data The requested data.
*
* @return mixed The primary key value of the saved record (true if missing).
* Returns false in case of failure.
*/
final protected function store(array $data)
{
// construct the object that will be saved
$table = $this->prepareSaveData($data);
if (!$table)
{
return false;
}
$db = JFactory::getDbo();
if (!empty($table->{$this->tableKeyName}))
{
// update needed
$res = $db->updateObject($this->tableName, $table, $this->tableKeyName);
}
else
{
// insert needed
$res = $db->insertObject($this->tableName, $table, $this->tableKeyName);
}
if (!$res)
{
// something went wrong while saving the record
return false;
}
// check again whether the PK has been filled
if (empty($table->{$this->tableKeyName}))
{
// no PK, just return true
return true;
}
return $table->{$this->tableKeyName};
}
/**
* Runs after saving the given data.
* It is possible to perform here some extra actions.
*
* @param array $data The saved data.
* @param boolean True in case of insert, false in case of update.
*
* @return void
*/
protected function postflight(array $data, $isNew)
{
$app = JFactory::getApplication();
/**
* Runs after saving the given data.
* It is possible to perform here some extra actions.
*
* @param array $data The saved data.
* @param boolean $isNew True in case of insert, false in case of update.
* @param self $model The current model.
*
* @return void
*
* @since 1.5.10
*/
$app->triggerEvent('onAfterSaveVikBooking' . ucfirst($this->getName()), [$data, $isNew, $this]);
}
/**
* Removes the specified item from the database.
*
* @param object $item The record to delete.
*
* @return boolean True if deleted, false otherwise.
*/
protected function remove($item)
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->delete($db->qn($this->tableName))
->where($db->qn($this->tableKeyName) . ' = ' . $db->q($item->{$this->tableKeyName}));
$db->setQuery($query);
$db->execute();
return (bool) $db->getAffectedRows();
}
/**
* Returns all the columns supported by the database table of this model.
*
* @return array
*/
public function getTableColumns()
{
if (!isset(static::$fields[$this->tableName]))
{
try
{
static::$fields[$this->tableName] = JFactory::getDbo()->getTableColumns($this->tableName);
}
catch (Exception $e)
{
static::$fields[$this->tableName] = [];
}
}
return static::$fields[$this->tableName];
}
}