我有一个Product
实体。每个产品可以有0或N张图片。我有一个ProductPhoto
实体,它具有order
属性(0 =第一)。
在页面上,我列出了当前产品的所有图片。我想用2个向上/向下箭头管理图片顺序。
当用户点击箭头时,它会相对于其他箭头向上/向下移动。
因此,在每个箭头上,有一个链接对应于我的ProductController
中的路线动作。
仅更新移动图片的顺序并不是很复杂,但我不知道如何更新ArrayCollection中其他图片的顺序...
/**
* Manage picture order
*
* @Route("/products/{id}/photos/{idphoto}/move-{direction}", name="prod_move_photo")
*/
public function movePhotoAction($id, $idphoto, $direction, Request $request) {
$em = $this->getDoctrine()->getManager();
$photo = $em->getRepository('AppBundle:ProductPhoto')->find($idphoto);
if ($direction == 'up') {
$order = $photo->getOrder() - 1;
if ($order >= 0)
$photo->setOrder($order);
else
$photo->setOrder(0);
} elseif ($direction == 'down') {
$order = $photo->getOrder() + 1;
$photo->setOrder($order);
} else {
throw $this->createNotFoundException("The type of ordering '" . $direction . "' doesn't exist.");
}
$em->flush();
// redirection
return $this->redirectToRoute('prod_photos', array('id' => $id));
}
也许使用PHP uksort()
?
看起来你想要更新两个互相移动的order
中的ProductPhoto
字段,对吧?所以请试试这个:
/**
* Manage picture order
*
* @Route("/products/{id}/photos/{idphoto}/move-{direction}", name="prod_move_photo")
*/
public function movePhotoAction($id, $idphoto, $direction, Request $request) {
$em = $this->getDoctrine()->getManager();
$photo = $em->getRepository('AppBundle:ProductPhoto')->find($idphoto);
$order = $photo->getOrder();
switch($direction) {
case 'up':
$newOrder = ($order >= 1) ? ($order - 1) : (int) 0;
break;
case 'down':
$newOrder = $order + 1;
break;
default:
throw $this->createNotFoundException("The type of ordering '" . $direction . "' doesn't exist.");
}
$anotherPhoto = $em->getRepository('AppBundle:ProductPhoto')->findOneByOrder($newOrder);
$photo->setOrder($newOrder);
$anotherPhoto->setOrder($order);
$em->flush();
// redirection
return $this->redirectToRoute('prod_photos', array('id' => $id));
}
@Snegirekk的解决方案效果非常好(我使用它),但这是我找到的解决方案,如果它可以帮助...
/**
* Manage picture order
*
* @Route("/products/{id}/photos/{idphoto}/move-{direction}", name="prod_move_photo")
*/
public function movePhotoAction($id, $idphoto, $direction, Request $request) {
$em = $this->getDoctrine()->getManager();
$photo = $em->getRepository('AppBundle:ProductPhoto')->find($idphoto);
// Current order of the photo
$currentPos = $photo->getOrder();
// Determine new order
if ($direction == 'up') {
$newPos = ($currentPos > 0) ? $currentPos - 1 : 0;
} elseif ($direction == 'down') {
$newPos = $currentPos + 1;
} else {
throw $this->createNotFoundException("The type of ordering '" . $direction . "' doesn't exist.");
}
$product = $em->getRepository('AppBundle:Product')->find($id);
// Get product photos with actual order (moveElement() needs an array)
$photos = $product->getPhotos()->toArray();
// Reorder photos in ArrayCollection
$this->moveElement($photos, $currentPos, $newPos);
// Reorder photos in database (with keys of formatted ArrayCollection)
foreach ($photos as $order => $p) {
$p->setOrder($order);
}
$em->flush();
// redirection
return $this->redirectToRoute('prod_photos', array('id' => $id));
}
/**
* Move an array element to a new index
*
* @param array $array Array of elements to sort
* @param integer $currentPos Current position of the element to move
* @param integer $newPos New position of the element to move
* @return void
*/
public function moveElement(&$array, $currentPos, $newPos) {
$out = array_splice($array, $currentPos, 1);
array_splice($array, $newPos, 0, $out);
}