Symfony 3:如何使用路由操作重新排序数组集合?
Symfony 3 : how to reordering an array collection with route action?
我有一个 Product
实体。每个产品可以有 0 或 N 张图片。
我有一个 ProductPhoto
实体,它有一个 order
属性 (0 = 第一个)。
在一个页面上,我列出了我当前产品的所有图片。我想用 2 up/down 个箭头管理图片顺序。
当用户单击箭头时,它会 up/down 将图片相对于其他图片移动。
所以,在每个箭头上,有一个 link 对应于我 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()
?
看起来您想更新两个 ProductPhoto
中相互移动的 order
字段,对吗?所以请试试这个:
/**
* 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);
}
我有一个 Product
实体。每个产品可以有 0 或 N 张图片。
我有一个 ProductPhoto
实体,它有一个 order
属性 (0 = 第一个)。
在一个页面上,我列出了我当前产品的所有图片。我想用 2 up/down 个箭头管理图片顺序。
当用户单击箭头时,它会 up/down 将图片相对于其他图片移动。
所以,在每个箭头上,有一个 link 对应于我 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()
?
看起来您想更新两个 ProductPhoto
中相互移动的 order
字段,对吗?所以请试试这个:
/**
* 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);
}