%PDF- %PDF-
| Direktori : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/ui/helpers/models/ |
| Current File : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/ui/helpers/models/ItemDrop.php |
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*
*/
/**
* Created by PhpStorm.
* User: davidborn
*/
namespace humhub\modules\ui\helpers\models;
use Yii;
use yii\base\Model;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
use yii\db\TableSchema;
use yii\db\Transaction;
use yii\db\Expression;
/**
* Class ItemDrop
* @since 1.4
*/
abstract class ItemDrop extends Model
{
/**
* @var ActiveRecord the model to resort
*/
private $model;
/**
* @var string ActiveRecord model class
*/
public $modelClass;
/**
* @var integer
*/
public $modelId;
/**
* @var integer new model index
*/
public $index;
/**
* @var string form submit name
*/
public $formName = 'ItemDrop';
/**
* @var integer|null the id of the target used for dragging items between lists
*/
public $targetId;
/**
* @var string|null a targetId field of the model e.g. list_id
*/
public $targetIdField;
/**
* @var ActiveQuery can be set instead of overwritting [getSortItemsQuery()]
* @see getSortItemsQuery()
*/
public $sortQuery;
/**
* @var string the sort order field of the model
*/
public $sortOrderField = 'sort_order';
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id', 'index', 'targetId'], 'integer']
];
}
/**
* @inheritdoc
*/
public function formName()
{
return $this->formName;
}
/**
* Handles the resorting of the list
* @return bool
*/
public function save()
{
try {
$this->moveItemIndex();
return true;
} catch (\Throwable $e) {
Yii::error($e);
}
return false;
}
/**
* Moves the given
* @param $id
* @param $newIndex
* @return bool
* @throws \Throwable
* @throws \yii\db\Exception
*/
protected function run()
{
/** @var $transaction Transaction */
$transaction = $this->beginTransaction();
try {
$model = $this->getModel();
$tableName = $this->getTableName();
// Load all items to sort and exclude the model we want to resort
$itemsToSort = $this->getSortItemsQuery()->andWhere(['!=', $tableName.'.id', $this->id])->all();
$newIndex = $this->validateIndex($this->index, $itemsToSort);
if($this->getSortOrder($model) === $newIndex) {
return true;
}
$this->updateTarget();
// Add our model to the new index
array_splice($itemsToSort, $newIndex, 0, [$model]);
foreach ($itemsToSort as $index => $item) {
$this->updateSortOrder($item, $index);
}
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollBack();
throw $e;
} catch (\Throwable $e) {
$transaction->rollBack();
throw $e;
}
}
/**
* @return Transaction
*/
protected function beginTransaction()
{
return call_user_func($this->modelClass.'::getDb')->beginTransaction();
}
/**
* Makes sure we use a valid sort index.
*
* @param $newIndex
* @param $itemsToSort
* @return int
*/
protected function validateIndex($newIndex, $itemsToSort)
{
if ($newIndex < 0) {
return 0;
} else if ($newIndex >= count($itemsToSort) + 1) {
return count($itemsToSort) - 1;
}
return $newIndex;
}
/**
* Returns the sort order (index) value of an model (by default a sort_order field).
*
* This may be overwritten if the model uses another sort order field.
*
* @param $model
* @return mixed
*/
protected function getSortOrder(ActiveRecord $model)
{
return $model->${$this->sortOrderField};
}
/**
* Updates the sort_order (index) of the given model instance (by default a sort_order field).
*
* This may be overwritten if the model uses another sort order field.
*
* @param $model
* @return mixed
*/
protected function updateSortOrder(ActiveRecord $model, $sortOrder)
{
return $model->updateAttributes([$this->sortOrderField => $sortOrder]);
}
/**
* @return string returns the table name of the model
*/
protected function getTableName()
{
/* @var $schema TableSchema */
$schema = call_user_func($this->modelClass.'::getTableSchema');
return $schema->fullName;
}
/**
* Loads and caches the model instance to resort.
*
* @param $id mixed
* @return ActiveRecord
*/
protected function getModel()
{
if(!$this->model) {
$this->model = $this->loadModel();
}
return $this->model;
}
/**
* Loads the model instance to resort
* @param $id
* @return ActiveRecord
*/
protected function loadModel()
{
return call_user_func($this->modelClass.'::findOne', ['id' => $this->id]);
}
/**
* Returns a query responsible for loading all items to resort.
* This this can be for example all models within a list:
*
* ```
* return MyItem::find()->where(['listId' => $this->targetId]);
* ```
*
* @return ActiveQuery
*/
protected function getSortItemsQuery() {
if($this->sortQuery) {
return $this->sortQuery;
}
$query = call_user_func($this->modelClass.'::find');
if($this->targetIdField) {
$query->where([$this->targetIdField => $this->targetId]);
}
return $query;
}
/**
* Responsible for updating the target on the model e.g:
*/
protected function updateTarget() {
if($this->targetIdField) {
$targetId = $this->targetId ? $this->targetId : new Expression('NULL');
$this->getModel()->updateAttributes([$this->targetIdField => $targetId]);
}
}
}