瀏覽代碼

Allow Deletion of Maintainers

Peter Buri 11 年之前
父節點
當前提交
d1019f1dfa

+ 74 - 3
src/Packagist/WebBundle/Controller/WebController.php

@@ -20,7 +20,8 @@ use Composer\Package\Loader\ValidatingArrayLoader;
 use Composer\Package\Loader\ArrayLoader;
 use Doctrine\ORM\NoResultException;
 use Packagist\WebBundle\Form\Type\AddMaintainerRequestType;
-use Packagist\WebBundle\Form\Model\AddMaintainerRequest;
+use Packagist\WebBundle\Form\Model\MaintainerRequest;
+use Packagist\WebBundle\Form\Type\RemoveMaintainerRequestType;
 use Packagist\WebBundle\Form\Type\SearchQueryType;
 use Packagist\WebBundle\Form\Model\SearchQuery;
 use Packagist\WebBundle\Package\Updater;
@@ -525,6 +526,9 @@ class WebController extends Controller
         if ($maintainerForm = $this->createAddMaintainerForm($package)) {
             $data['form'] = $maintainerForm->createView();
         }
+        if ($removeMaintainerForm = $this->createRemoveMaintainerForm($package)) {
+            $data['removeMaintainerForm'] = $removeMaintainerForm->createView();
+        }
         if ($deleteForm = $this->createDeletePackageForm($package)) {
             $data['deleteForm'] = $deleteForm->createView();
         }
@@ -770,6 +774,61 @@ class WebController extends Controller
         return $data;
     }
 
+    /**
+     * @Template("PackagistWebBundle:Web:viewPackage.html.twig")
+     * @Route("/packages/{name}/remove_maintainers/", name="remove_maintainer", requirements={"name"="[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+"})
+     */
+    public function removeMaintainerAction(Request $req, $name)
+    {
+        /** @var $package Package */
+        $package = $this->getDoctrine()
+            ->getRepository('PackagistWebBundle:Package')
+            ->findOneByName($name);
+
+        if (!$package) {
+            throw new NotFoundHttpException('The requested package, '.$name.', was not found.');
+        }
+        if (!$removeMaintainerForm = $this->createRemoveMaintainerForm($package)) {
+            throw new AccessDeniedException('You must be a package\'s maintainer to modify maintainers.');
+        }
+
+        $data = array(
+            'package' => $package,
+            'removeMaintainerForm' => $removeMaintainerForm->createView(),
+            'show_remove_maintainer_form' => true,
+        );
+
+        if ('POST' === $req->getMethod()) {
+            $removeMaintainerForm->bind($req);
+            if ($removeMaintainerForm->isValid()) {
+                try {
+                    $em = $this->getDoctrine()->getManager();
+                    $user = $removeMaintainerForm->getData()->getUser();
+
+                    if (!empty($user)) {
+                        if ($package->getMaintainers()->contains($user)) {
+                            $package->getMaintainers()->removeElement($user);
+                        }
+
+                        $em->persist($package);
+                        $em->flush();
+
+                        $this->get('session')->getFlashBag()->set('success', $user->getUsername().' is no longer a '.$package->getName().' maintainer.');
+
+                        return new RedirectResponse($this->generateUrl('view_package', array('name' => $package->getName())));
+                    }
+                    $this->get('session')->getFlashBag()->set('error', 'The user could not be found.');
+                } catch (\Exception $e) {
+                    $this->get('logger')->crit($e->getMessage(), array('exception', $e));
+                    $this->get('session')->getFlashBag()->set('error', 'The maintainer could not be removed.');
+                }
+            }
+        }
+
+        $data['searchForm'] = $this->createSearchForm()->createView();
+        return $data;
+    }
+
     /**
      * @Route("/statistics", name="stats")
      * @Template
@@ -887,8 +946,20 @@ class WebController extends Controller
         }
 
         if ($this->get('security.context')->isGranted('ROLE_EDIT_PACKAGES') || $package->getMaintainers()->contains($user)) {
-            $addMaintainerRequest = new AddMaintainerRequest;
-            return $this->createForm(new AddMaintainerRequestType, $addMaintainerRequest);
+            $maintainerRequest = new MaintainerRequest;
+            return $this->createForm(new AddMaintainerRequestType, $maintainerRequest);
+        }
+    }
+
+    private function createRemoveMaintainerForm(Package $package)
+    {
+        if (!($user = $this->getUser()) || 1 == $package->getMaintainers()->count()) {
+            return;
+        }
+
+        if ($this->get('security.context')->isGranted('ROLE_EDIT_PACKAGES') || $package->getMaintainers()->contains($user)) {
+            $maintainerRequest = new MaintainerRequest;
+            return $this->createForm(new RemoveMaintainerRequestType(), $maintainerRequest, array('package'=>$package, 'excludeUser'=>$user));
         }
     }
 

+ 16 - 0
src/Packagist/WebBundle/Entity/UserRepository.php

@@ -25,4 +25,20 @@ class UserRepository extends EntityRepository
             ->where('u.apiToken IS NULL');
         return $qb->getQuery()->getResult();
     }
+
+    public function getPackageMaintainersQueryBuilder(Package $package, User $excludeUser=null)
+    {
+        $qb = $this->createQueryBuilder('u')
+            ->select('u')
+            ->innerJoin('u.packages', 'p', 'WITH', 'p.id = :packageId')
+            ->setParameter(':packageId', $package->getId())
+            ->orderBy('u.username', 'ASC');
+
+        if ($excludeUser) {
+            $qb->andWhere('u.id <> :userId')
+                ->setParameter(':userId', $excludeUser->getId());
+        }
+
+        return $qb;
+    }
 }

+ 1 - 1
src/Packagist/WebBundle/Form/Model/AddMaintainerRequest.php → src/Packagist/WebBundle/Form/Model/MaintainerRequest.php

@@ -14,7 +14,7 @@ namespace Packagist\WebBundle\Form\Model;
 
 use FOS\UserBundle\Model\UserInterface;
 
-class AddMaintainerRequest
+class MaintainerRequest
 {
     protected $user;
 

+ 1 - 1
src/Packagist/WebBundle/Form/Type/AddMaintainerRequestType.php

@@ -29,7 +29,7 @@ class AddMaintainerRequestType extends AbstractType
     public function setDefaultOptions(OptionsResolverInterface $resolver)
     {
         $resolver->setDefaults(array(
-            'data_class' => 'Packagist\WebBundle\Form\Model\AddMaintainerRequest',
+            'data_class' => 'Packagist\WebBundle\Form\Model\MaintainerRequest',
         ));
     }
 

+ 50 - 0
src/Packagist/WebBundle/Form/Type/RemoveMaintainerRequestType.php

@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of Packagist.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *     Nils Adermann <naderman@naderman.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Packagist\WebBundle\Form\Type;
+
+use Doctrine\ORM\EntityRepository;
+use Packagist\WebBundle\Entity\Package;
+use Packagist\WebBundle\Entity\User;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class RemoveMaintainerRequestType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder->add('user', 'entity', array(
+            'class' => 'PackagistWebBundle:User',
+            'query_builder' => function(EntityRepository $er) use ($options) {
+                return $er->getPackageMaintainersQueryBuilder($options['package'], $options['excludeUser']);
+            },
+        ));
+    }
+
+    public function setDefaultOptions(OptionsResolverInterface $resolver)
+    {
+        $resolver->setRequired(array('package'));
+        $resolver->setDefaults(array(
+            'excludeUser' => null,
+            'data_class' => 'Packagist\WebBundle\Form\Model\MaintainerRequest'
+        ));
+    }
+
+    public function getName()
+    {
+        return 'remove_maintainer_form';
+    }
+}

+ 4 - 0
src/Packagist/WebBundle/Resources/public/js/view.js

@@ -3,6 +3,10 @@
         $('#add-maintainer-form').toggleClass('hidden');
         e.preventDefault();
     });
+    $('#remove-maintainer').click(function (e) {
+        $('#remove-maintainer-form').toggleClass('hidden');
+        e.preventDefault();
+    });
     $('.package .version h1').click(function (e) {
         e.preventDefault();
         $(this).siblings('.details-toggler').click();

+ 31 - 14
src/Packagist/WebBundle/Resources/views/Web/viewPackage.html.twig

@@ -74,7 +74,7 @@
                 {% for maintainer in package.maintainers %}
                     <a href="{{ path('user_profile', {'name': maintainer.username}) }}">{{ maintainer.username }}</a>{{ loop.last ? '' : ', ' }}
                 {% endfor %}
-                {% if form is defined %}(<a id="add-maintainer" href="{{ path('add_maintainer', {'name': package.name}) }}">add maintainer</a>){% endif %}
+                {% if form is defined or removeMaintainerForm is defined %}({% if form is defined %}<a id="add-maintainer" href="{{ path('add_maintainer', {'name': package.name}) }}">add maintainer</a>{% endif %}{% if form is defined and removeMaintainerForm is defined %} / {% endif %}{% if removeMaintainerForm is defined %}<a id="remove-maintainer" href="{{ path('remove_maintainer', {'name': package.name}) }}">remove maintainer</a>{% endif %}){% endif %}
                 <br />
                 {% if version and version.homepage %}
                     <span>Homepage:</span> <a href="{{ version.homepage }}">{{ version.homepage|replace({'http://': ''}) }}</a><br />
@@ -98,20 +98,37 @@
                 {% endif %}
             </p>
 
-            {% if form is defined %}
+            {% if form is defined or removeMaintainerForm is defined %}
                 <div>
-                    <form id="add-maintainer-form" class="{{ show_maintainer_form|default(false) ? '': 'hidden' }}" action="{{ path('add_maintainer', {'name': package.name}) }}" method="POST" {{ form_enctype(form) }}>
-                        <div>
-                            <h2>Add Maintainer</h2>
-                            <p>
-                                {{ form_label(form.user, "Username") }}
-                                {{ form_errors(form.user) }}
-                                {{ form_widget(form.user) }}
-                            </p>
-                            {{ form_rest(form) }}
-                            <input id="submit" type="submit" value="Submit" />
-                        </div>
-                    </form>
+                    {% if form is defined %}
+                        <form id="add-maintainer-form" class="{{ show_maintainer_form|default(false) ? '': 'hidden' }}" action="{{ path('add_maintainer', {'name': package.name}) }}" method="POST" {{ form_enctype(form) }}>
+                            <div>
+                                <h2>Add Maintainer</h2>
+                                <p>
+                                    {{ form_label(form.user, "Username") }}
+                                    {{ form_errors(form.user) }}
+                                    {{ form_widget(form.user) }}
+                                </p>
+                                {{ form_rest(form) }}
+                                <input id="submit" type="submit" value="Submit" />
+                            </div>
+                        </form>
+                    {% endif %}
+
+                    {% if removeMaintainerForm is defined %}
+                        <form id="remove-maintainer-form" class="{{ show_remove_maintainer_form|default(false) ? '': 'hidden' }}" action="{{ path('remove_maintainer', {'name': package.name}) }}" method="POST" {{ form_enctype(removeMaintainerForm) }}>
+                            <div>
+                                <h2>Remove Maintainer</h2>
+                                <p>
+                                    {{ form_label(removeMaintainerForm.user, "Username") }}
+                                    {{ form_errors(removeMaintainerForm.user) }}
+                                    {{ form_widget(removeMaintainerForm.user) }}
+                                </p>
+                                {{ form_rest(removeMaintainerForm) }}
+                                <input id="submit" type="submit" value="Submit" />
+                            </div>
+                        </form>
+                    {% endif %}
                 </div>
             {% endif %}