-2
A
回答
0
我发现这个代码前一阵子(可惜不记得在哪里。所有学分原作者),并编辑了一下我的需求
它添加到您要使用的排序上
的table
$this->addBehavior('Sortable', [
'field' => 'sort'
]);
,并保存这/src/Model/Behaviour/SortableBehaviour.php
<?php
namespace App\Model\Behavior;
use Cake\Database\Expression\QueryExpression;
use Cake\Event\Event;
use Cake\ORM\Behavior;
use Cake\ORM\Entity;
use Cake\ORM\Exception\RecordNotFoundException;
use Cake\ORM\Table;
use Cake\ORM\Query;
class SortableBehavior extends Behavior {
protected $_table;
/**
* Default config
*
* These are merged with user-provided config when the behavior is used.
*
* field
* - the field in the DB-table that is doing the sorting
* scope
* - one or more foreign_keys as array
* - eg ['user_group_id'] in a table users would enabled sorting for each
* - user_group separately
* newEntries
* - either `last` or `first`
*
* @var array
*/
protected $_defaultConfig = [
'field' => 'sort',
'scope' => null,
'newEntries' => 'last'
];
/**
* Constructor
*
* @param \Cake\ORM\Table $table The table this behavior is attached to.
* @param array $config The config for this behavior.
*/
public function __construct(Table $table, array $config = []) {
parent::__construct($table, $config);
$this->_table = $table;
}
/**
* Before save listener
* handles initial sorting for added entities
* @param \Cake\Event\Event $event The beforeSave event that was fired
* @param \Cake\ORM\Entity $entity the entity that is going to be saved
* @return void
*/
public function beforeSave(Event $event, Entity $entity) {
$config = $this->config();
if (!$entity->isNew()) {
return;
}
if ($config['newEntries'] == 'last') {
$scopeData = $this->_getScopeData($entity);
$maxPosition = $this->_getMaxPosition($scopeData);
$entity->set($config['field'], $maxPosition + 1);
}
}
/**
* After delete listener
*
* makes sure the left over entities are sorted properly
*
* @param \Cake\Event\Event $event The afterDelete event that was fired
* @param \Cake\ORM\Entity $entity the entity that was going to be deleted
* @return void
*/
public function afterDelete(Event $event, Entity $entity) {
$config = $this->config();
$expression = new QueryExpression($config['field'] . ' = ' . $config['field'] . ' - 1');
$conditions = [
$config['field'].' >' => $entity->get($config['field'])
];
$conditions += $this->_getScopeData($entity);
$this->_table->updateAll($expression, $conditions);
}
/**
* main move method
*
*
*
* @param integer $id the id of the Entity that was moved
* @param array $newSortOrder all IDs of the current scope in the desired sort order (as provided by http://johnny.github.io/jquery-sortable/)
* @return boolean
*
*/
public function move($id, $newSortOrder) {
return $this->_table->connection()->transactional(function() use ($id, $newSortOrder) {
return $this->_move($id, $newSortOrder);
});
}
/**
* helper method that contains the actual move code
*
* @param integer $id the id of the Entity that was moved
* @param array $newSortOrder all IDs of the current scope in the desired sort order (as provided by http://johnny.github.io/jquery-sortable/)
* @return boolean
*
*/
protected function _move($id, $newSortOrder) {
$config = $this->config();
$node = $this->_getNode($id);
$current_position = $node[$config['field']];
// might be faster to do array_flip?!
$new_position = array_search($id, $newSortOrder) + 1;
// no position change -> return
if ($current_position == $new_position) {
return true;
}
// build sql for updating affected entries
if ($current_position < $new_position) {
$expression = new QueryExpression($config['field'] . ' = ' . $config['field'] . ' - 1');
$conditions = [
'sort >' => $current_position,
'AND' => [ $config['field'].' <=' => $new_position ],
];
} else {
$expression = new QueryExpression($config['field'] . ' = ' . $config['field'] . ' + 1');
$conditions = [
'sort <' => $current_position,
'AND' => [ $config['field'].' >=' => $new_position ],
];
}
$conditions += $this->_getScopeData($node);
$res = $this->_table->updateAll($expression, $conditions);
// finally set the inital field to the new val
$q = $this->_table->query();
return $res && $q->update()
->set([$config['field']=>$new_position])
->where(['id'=>$id])
->execute();
}
/**
* returns a node and the scope params if set up in config
* @param integer $id the node id
* @return Array|Object the result of query->first()
* @throws Cake\ORM\Exception\RecordNotFoundException if no node with that id found
*/
protected function _getNode($id) {
$config = $this->config();
// get current sort of `id`
// if a context is set -> get that also while we are aclling this
$query = $this->_table->find();
$query
->select(array_merge(['id', $config['field']], (array)$config['scope']))
->where(['id'=>$id])
->contain();
if (!$node = $query->first()) {
throw new RecordNotFoundException(sprintf('Kein Eintrag mit ID %s gefunden', $id));
}
return $node;
}
/**
* returns the highest position within that scope
*
* @param array $scopeData the scope data
* @return integer the currently highest positions in that scope
*/
protected function _getMaxPosition($scopeData=null) {
$config = $this->config();
$query = $this->_table->find();
$query
->select(array_merge([$config['field']], array_keys($scopeData)))
->where($scopeData)
->order([$config['field'] => 'DESC'])
->contain();
$node = $query->first();
return ($node[$config['field']] ?: 0);
}
protected function _getScopeData($node) {
$config = $this->config();
$conditions = [];
foreach ((array)$config['scope'] as $scope) {
$conditions[$scope] = $node[$scope];
}
return $conditions;
}
}
这增加了全自动增加值排序,也可以提供排序(你需要动作到控制器类)
希望可以帮到
相关问题
- 1. 如何在linq订购最大数量
- 2. cakephp3:保存相关数据
- 3. 订购大数值
- 4. 选择订购了最大数量产品的客户?
- 5. Magento的 - 最小订购量的变化到最大订单金额
- 6. 用cakephp3保存图像
- 7. 通过订购数量的数量修改库存量
- 8. Sql Server的订购最大值
- 9. 订购全文中最大的比赛
- 10. 订购结果w /非标准订购(数量上升但最终为w/0)&为每行添加行号。
- 11. HTML5 pattern订购号
- 12. 保存/存储客户采购订单数据的最佳方法?
- 13. MySQL的数量订购
- 14. C#更改订购数量
- 15. 订购VARCHAR和数量
- 16. Sharetribe:改变“最小订购量”到“最小订单”
- 17. 最快的方法来订购一个巨大的矢量?
- 18. 搜索大量的订购字符串
- 19. 关于Hibernate批量大小订购
- 20. 保存功能订购PHPDoc的
- 21. 购物车存货编号和数量
- 22. 订购最高和最低
- 23. 将数据的订购清单保存到核心数据中
- 24. 如何使用Rails以最大数量的相同条目进行订购?
- 25. Java - 订购3个号码
- 26. 订购版本号为
- 27. TSQL对订购集编号
- 28. 7.1 <7.10 - 订购号码
- 29. C#不同型号订购
- 30. 河内塔订购号码