我有一个使用 CakePHP 中的 TreeBehavior 的 MPTT。树验证但是当我添加一个新的根节点时它可以工作。当我尝试通过$this->{Model}->save($data)
where $data
now has ['{Model}']['parent_id']
set 将子节点添加到该节点时,它会更新父节点lft
和rght
字段以容纳新子节点,但新子节点lft
的rght
值为 0。
知道我可能会出错的地方吗?
我尝试将 lft 和 rght 设置为 null 以及取消设置,但无济于事。
模型
`class Image extends AppModel {
public $displayField = 'title';
public $actsAs = array('Polymorphic', 'Tree');
public $imageResource = false;
// Define virtual fiels at runtime
public function __construct($id=false,$table=null,$ds=null){
parent::__construct($id,$table,$ds);
$this->virtualFields = array(
'path' => "CONCAT('db/', {$this->alias}.uuid, '.', {$this->alias}.ext)"
);
$categories = $this->ImageCategory->find('list', array('fields' => array('ImageCategory.id')));
$this->order = array('FIELD('.$this->alias.'.image_category_id, '.String::toList($categories, ', ').')');
}
public function save($data = null, $validate = true, $fieldList = array()) {
if($this->imageResource === false) {
if(!$this->loadImage(APP.'webroot'.DS.$this->path)) {
if(!$this->loadImage(APP.'webroot'.DS.'db'.DS.$this->uuid.'.'.$this->ext)) {
if(!$this->loadImage(APP.'webroot'.DS.'db'.DS.$data['Image']['uuid'].'.'.$data['Image']['ext'])) {
// Image doesn't exist so we create a new one.
//die('failed to load GD Library image resource');
//$this->saveNew($data, $validate, fieldList);
//$this->uses[] = 'OrigionalImage';
$this->loadImage(APP.'webroot'.DS.'img'.DS.'db'.DS.$this->data['Image']['uuid'].'.'.$this->data['Image']['ext']);
}
}
}
}
$data['Image']['width'] = $this->getWidth();
$data['Image']['height'] = $this->getHeight();
$this->writeToDisk(APP.'webroot'.DS.'img'.DS.'db'.DS.$this->uuid.'.jpg');
//pr($data);exit;
return parent::save($data, $validate, $fieldList);
}
public function saveNew($data = null, $validate = true, $fieldList = array()) {
$parentId = $data['Image']['parent_id'];
$this->recursive = -1;
$parentData = $this->readDataOnly(null, $parentId);
unset($parentData[$parentData['Image']['class']]);
if(!empty($parentData)) {
$data = array();
$data['Image']['parent_id'] = $parentId;
$data['Image']['class'] = $parentData['Image']['class'];
$data['Image']['foreign_id'] = $parentData['Image']['foreign_id'];
$data['Image']['title'] = $parentData['Image']['title'];
$data['Image']['alt'] = $parentData['Image']['alt'];
$data['Image']['image_category_id'] = $parentData['Image']['image_category_id'];
$data['Image']['image_type_id'] = $parentData['Image']['image_type_id'];
$data['Image']['ext'] = 'jpg';
$data['Image']['id'] = null;
$data['Image']['uuid'] = $this->uuid = String::uuid();
return $this->save($data, $validate, $fieldList);
}
return false;
}
public function saveToDB($data = null, $validate = true, $fieldList = array()) {
if($this->imageResource !== false) {
$data['Image']['width'] = $this->getWidth();
$data['Image']['height'] = $this->getHeight();
}
return parent::save($data, $validate, $fieldList);
}
public function read($fields = null, $id = null) {
if(parent::read($fields, $id)) {
$this->loadImage(APP.'webroot'.DS.'img'.DS.$this->data['Image']['path']);
return parent::read($fields, $id);
}
return false;
}
public function readDataOnly($fields = null, $id = null) {
return parent::read($fields, $id);
}
public function create($data = array(), $filterKey = false) {
if(parent::create($data, $filterKey)) {
$this->uuid = $this->data['Image']['uuid'] = String::uuid();
return true;
} else {
return false;
}
}
public function delete() {
unlink(APP.'webroot'.DS.'img'.DS.'db'.DS.$this->data['Image']['uuid'].'.'.$this->data['Image']['ext']);
return parent::delete();
}
public function loadImage($fileString) {
if(!file_exists($fileString)) {
throw new NotFoundException('File: "'.$fileString.'" not found');
return false;
}
//if(empty($this->ext))
$this->ext = strtolower(pathinfo($fileString, PATHINFO_EXTENSION));
// create useing the correct function
switch($this->ext) {
case 'jpg':
$this->imageResource = imagecreatefromjpeg($fileString);
break;
case 'jpeg':
$this->imageResource = imagecreatefromjpeg($fileString);
break;
case 'png':
$this->imageResource = imagecreatefrompng($fileString);
break;
case 'gif';
$this->imageResource = imagecreatefromgif($fileString);
break;
default:
throw new NotFoundException('File "'.$fileString.'" not found');
return false; // just in case
break; // just in case
}
imagealphablending($this->imageResource, true);
return true;
}
public function handelUpload($data = array()) {
$this->file = $data['Image']['file'];
if ($this->file['error'] == false) {
if(
$this->file['type'] == 'image/jpeg' ||
$this->file['type'] == 'image/jpg' ||
$this->file['type'] == 'image/png' ||
$this->file['type'] == 'image/gif'
) {
$this->uuid = String::uuid();
$this->set('uuid', $this->uuid);
$this->ext = strtolower(pathinfo($this->file['name'], PATHINFO_EXTENSION));
$this->set('ext', $this->ext);
$fileLocation = APP.'webroot'.DS.'img'.DS.'db'.DS.$this->uuid.'.'.$this->ext;
if (move_uploaded_file($this->file['tmp_name'], $fileLocation)) {
$this->loadImage($fileLocation);
$this->set('width', $this->getWidth());
$this->set('height', $this->getHeight());
return true;
}
return false;
}
}
}
public function resizeCrop($newWidth, $newHeight) {
$origWidth = $this->getWidth();
$origHeight = $this->getHeight();
$origRatio = $origWidth / $origHeight;
$desired_aspect_ratio = $newWidth / $newHeight;
if ($origRatio > $desired_aspect_ratio) {
/*
* Triggered when source image is wider
*/
$temp_height = $newHeight;
$temp_width = (int)($newHeight * $origRatio);
} else {
/*
* Triggered otherwise (i.e. source image is similar or taller)
*/
$temp_width = $newWidth;
$temp_height = (int)($newWidth / $origRatio);
}
/*
* Resize the image into a temporary GD image
*/
$temp_gdim = imagecreatetruecolor($temp_width, $temp_height);
imagecopyresampled($temp_gdim, $this->imageResource, 0, 0, 0, 0, $temp_width, $temp_height, $origWidth, $origHeight);
/*
* Copy cropped region from temporary image into the desired GD image
*/
$x0 = ($temp_width - $newWidth) / 2;
$y0 = ($temp_height - $newHeight) / 2;
$desired_gdim = imagecreatetruecolor($newWidth, $newHeight);
imagecopy($desired_gdim, $temp_gdim, 0, 0,$x0, $y0,$newWidth, $newHeight);
$this->imageResource = $desired_gdim;
return true;
}
public function crop($startX, $startY, $newWidth, $newHeight) {
$image_p = imagecreatetruecolor($newWidth, $newHeight);
$transparent = imagecolorallocatealpha($image_p, 255, 255, 255, 127);
imagealphablending($image_p, false);
imagesavealpha($image_p,true);
imagefilledrectangle($image_p, 0, 0, $newWidth, $newHeight, $transparent);
imagecopyresampled($image_p, $this->imageResource, 0, 0, $startX, $startY, $newWidth, $newHeight, $newWidth, $newHeight);
$this->imageResource = $image_p;
return true;
}
public function resizePercent($percent) {
(float)$percent = $percent/100;
// Get new dimensions
list($width, $height) = $this->getimageResourcesize($image);
$new_width = $width * $percent;
$new_height = $height * $percent;
// Resample
$image_p = imagecreatetruecolor($new_width, $new_height);
imagealphablending($image_p, false);
imagesavealpha($image_p,true);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
$this->imageResource = $image_p;
return true;
}
public function stream($quality = 100) {
switch(strtolower($this->ext)) {
case 'jpg':
header("Content-Type: image/jpeg");
imagejpeg($this->imageResource, null, $quality);
break;
case 'jpeg':
header("Content-Type: image/jpeg");
imagejpeg($this->imageResource, null, $quality);
break;
case 'png':
header("Content-Type: image/png");
imagepng($this->imageResource, null, $quality);
break;
case 'gif';
header("Content-Type: image/gif");
imagegif($this->imageResource, null, $quality);
break;
default:
throw new NotFoundException('File "'.$fileString.'" not found');
return false; // just in case
break; // just in case
}
return true;
}
public function writeToDisk($location = null, $quality = 100) {
if(!isset($this->ext) || empty($this->ext)) $this->ext = 'jpg';
if($location == null) $location = APP.'webroot'.DS.'img'.DS.'db'.DS.$this->uuid.'.'.$this->ext;
switch(strtolower($this->ext)) {
case 'jpg':
imagejpeg($this->imageResource, $location, $quality);
break;
case 'jpeg':
imagejpeg($this->imageResource, $location, $quality);
break;
case 'png':
imagepng($this->imageResource, $location, (($quality-100)/10));
break;
case 'gif';
imagegif($this->imageResource, $location, $quality);
break;
default:
throw new NotFoundException('File "'.$fileString.'" not found');
return false; // just in case
break; // just in case
}
return TRUE;
}
private function turnAlphaBlendingOFF() { imagealphablending($im, false); }
private function getImageResourceSize() {
$dim = array();
$dim[] = $this->getWidth($this->imageResource);
$dim[] = $this->getHeight($this->imageResource);
return $dim;
}
public function getWidth() {
return imagesx($this->imageResource);
}
public function getHeight() {
return imagesy($this->imageResource);
}
public $validate = array(
'original_image_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'uuid' => array(
'uuid' => array(
'rule' => array('uuid'),
),
),
'ext' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
'class' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
'foreign_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'title' => array(
'notempty' => array(
'rule' => array('notempty'),
),
),
'image_category_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'image_type_id' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'width' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
'height' => array(
'numeric' => array(
'rule' => array('numeric'),
),
),
);
public $hasOne = array(
'OriginalImage' => array(
'className' => 'Image',
'foreignKey' => 'id',
'conditions' => array('OriginalImage.parent_id' => 'OriginalImage.id', 'OriginalImage.id' => NULL),
),
'PrimaryImage' => array(
'className' => 'Image',
'foreignKey' => 'id',
'conditions' => array('PrimaryImage.primary' => 1),
)
);
public $belongsTo = array(
'ImageCategory' => array(
'className' => 'ImageCategory',
'foreignKey' => 'image_category_id'
),
'ImageType' => array(
'className' => 'ImageType',
'foreignKey' => 'image_type_id'
)
);
控制器
class ImagesController extends AppController {
public $paginate = array(
'limit' => 8,
'order' => 'Image.created DESC',
);
public $helpers = array('Js' => array('Jquery'));
public function admin_index() {
$this->Image->recursive = 0;
// Keywords
if(isset($this->passedArgs['Image.search']) && $this->passedArgs['Image.search'] != '') {
$keywords = $this->passedArgs['Image.search'];
$this->paginate['conditions'][] = array(
'OR' => array(
'Image.title LIKE' => "%$keywords%",
'Image.alt LIKE' => "%$keywords%",
)
);
$this->Image->data['Image']['Search'] = $keywords;
$title[] = __('Search',true).': '.$keywords;
}
// Width
if(isset($this->passedArgs['Image.width']) && $this->passedArgs['Image.width'] != '') {
$width = $this->passedArgs['Image.width'];
$this->paginate['conditions'][] = array(
'Image.width BETWEEN ? AND ?' => array($width-5, $width+5),
);
$this->Image->data['Image']['width'] = $width;
$title[] = __('Search',true).': '.$width;
}
// Height
if(isset($this->passedArgs['Image.height']) && $this->passedArgs['Image.height'] != '') {
$height = $this->passedArgs['Image.height'];
$this->paginate['conditions'][] = array(
'Image.height BETWEEN ? AND ?' => array($height-5, $height+5),
);
$this->Image->data['Image']['height'] = $height;
$title[] = __('Search',true).': '.$height;
}
// class
if(isset($this->passedArgs['Image.class']) && $this->passedArgs['Image.class'] != '') {
$class = $this->passedArgs['Image.class'];
$this->paginate['conditions'][] = array(
'Image.class LIKE' => $class,
);
$this->Image->data['Image']['class'] = $class;
$title[] = __('Search',true).': '.$class;
}
$this->set('count', $this->Image->find('count'));
$this->set('images', $this->paginate('Image', null, array('limit' => 8)));
}
public function admin_view($id = null) {
$this->Image->id = $id;
if (!$this->Image->exists()) {
throw new NotFoundException(__('Invalid image'));
}
$this->set('image', $this->Image->readDataOnly(null, $id));
if($this->Image->data['Image']['parent_id'] == null) {
$this->set('related', $this->Image->children($id, false, null, null, null ,1, 0));
} else {
$this->set('related', $this->Image->children($this->Image->data['Image']['parent_id'], false, null, null, null ,1, -1));
}
}
public function admin_add() {
$this->uses[] = 'Image';
$this->Image->create();
if($this->request->is('post')) {
if($this->Image->handelUpload($this->request->data) && $this->Image->saveToDB($this->request->data)) {
// Make thumbnails
if(true) {
$newParentId = $this->Image->getLastInsertID();
$this->Image->read(null, $newParentId);
$sizes = Configure::read('Image.thumbs.'.$this->Image->data['Image']['class']);
$numberOfResizes = 0;
foreach($sizes as $w => $h) {
if($this->Image->data['Image']['width']!=$w && $this->Image->data['Image']['height']!=$h) {
$this->Image->read(null, $newParentId);
$this->Image->resizeCrop($w, $h);
$this->request->data['Image']['parent_id'] = $this->Image->data['Image']['id'];
if($this->Image->saveNew($this->request->data)) {
$numberOfResizes++;
} else {
$this->Session->setFlash(__('A resized image could not be saved.'));
}
}
}
}
} else {
$this->Session->setFlash(__('The original image could not be saved. Please, try again.'));
}
$this->Session->setFlash(__('The image has been saved with '.$numberOfResizes.' resize(s)!'));
$this->redirect(array('controller' => 'images', 'action' => 'add', 'admin' => true));
}
$imageCategories = $this->Image->ImageCategory->generateTreeList(null,null,null,'-> ');
$imageTypes = $this->Image->ImageType->find('list');
$this->set(compact('imageSubcategories', 'imageTypes', 'imageCategories'));
}
public function admin_edit($id = null) {
$this->Image->id = $id;
if (!$this->Image->exists()) {
throw new NotFoundException(__('Invalid image'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if(!empty($this->request->data['Image']['file'])) {
$children = $this->Image->children($this->request->data['Image']['id']);
pr($children);exit;
if($this->Image->handelReUpload($this->request->data) && $this->Image->saveToDB($this->request->data)) {
// Make thumbnails
if(true) {
$this->Image->read(null, $this->Image->data['Image']['id']);
foreach($sizes as $w => $h) {
if($this->Image->data['Image']['width'] != $w && $this->Image->data['Image']['height'] != $h){
$this->Image->resizeCrop($w, $h);
unset($this->Image->data['Image']['modified']);
if($this->Image->data['Image']['parent_id'] == NULL) {
$this->request->data['Image']['parent_id'] = $this->Image->id;
if($this->Image->save($this->request->data)) {
$this->Session->setFlash(__('The image has been saved!'));
$this->redirect(array('controller' => 'images', 'action' => 'add', 'admin' => true));
}
$this->Session->setFlash(__('The image could not be saved. Please, try again.'));
}
}
}
}
$this->redirect(array('action' => 'view', $this->Image->id));
} else {
$this->Session->setFlash(__('The image could not be saved. Please, try again.'));
}
} else {
}
}
$imageCategories = $this->Image->ImageCategory->find('list');
$imageTypes = $this->Image->ImageType->find('list');
$this->request->data = $image = $this->Image->read(null, $id);
$this->set(compact('imageCategories', 'imageTypes', 'image'));
}
public function admin_delete($id = null) {
if (!$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->Image->id = $id;
if (!$this->Image->exists()) {
throw new NotFoundException(__('Invalid image'));
}
$this->Image->readDataOnly(null, $id);
if ($this->Image->delete()) {
$this->Session->setFlash(__('Image deleted'));
$this->redirect($this->referer());
}
$this->Session->setFlash(__('Image was not deleted'));
$this->redirect(array('action' => 'index'));
}
public function admin_recover() {
$this->Image->recover('parent');
/*
$condidtions[] = array('Image.parent_id !=' => null);
$this->Image->recursive = -1;
$images = $this->Image->find('all', array('conditions' => $condidtions, 'order' =>array('Image.id'), 'fields' => array('id', 'title', 'width', 'height')));
pr($images);
foreach($images as $id => $title) {
$this->Image->readDataOnly(null, $id);
$this->Image->delete();
}
*
*/
}
public function admin_verify() {
pr($this->Image->verify());
exit;
}