Browse Source

Merge remote-tracking branch 'rdohms/192-deprecated'

Jordi Boggiano 10 years ago
parent
commit
bcffaa9d42

+ 86 - 0
src/Packagist/WebBundle/Controller/PackageController.php

@@ -2,6 +2,7 @@
 
 namespace Packagist\WebBundle\Controller;
 
+use Packagist\WebBundle\Form\Type\AbandonedType;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Security\Core\Exception\AccessDeniedException;
@@ -68,5 +69,90 @@ class PackageController extends Controller
             "package" => $package, "form" => $form->createView()
         );
     }
+
+    /**
+     * @param Request $request
+     * @param string $name
+     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
+     *
+     * @Route(
+     *      "/packages/{name}/abandon",
+     *      name="abandon_package",
+     *      requirements={"name"="[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+?"}
+     * )
+     * @Template()
+     */
+    public function abandonAction(Request $request, $name)
+    {
+        /** @var $packageRepo \Packagist\WebBundle\Entity\PackageRepository */
+        $packageRepo = $this->getDoctrine()->getRepository('PackagistWebBundle:Package');
+
+        /** @var $package Package */
+        $package = $packageRepo->findOneByName($name);
+
+        if (!$package) {
+            throw $this->createNotFoundException("The requested package, $name, could not be found.");
+        }
+
+        if (!$package->getMaintainers()->contains($this->getUser()) && !$this->get('security.context')->isGranted('ROLE_EDIT_PACKAGES')) {
+            throw new AccessDeniedException;
+        }
+
+        $form = $this->createForm(new AbandonedType());
+        $form->handleRequest($request);
+
+        if ($form->isValid()) {
+
+            $package->setAbandoned(true);
+            $package->setReplacementPackage($form->get('replacement')->getData());
+
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($package);
+            $em->flush();
+
+            return $this->redirect($this->generateUrl('view_package', array('name' => $package->getName())));
+        }
+
+        return array(
+            'package' => $package,
+            'form'    => $form->createView()
+        );
+    }
+
+    /**
+     * @param string $name
+     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
+     *
+     * @Route(
+     *      "/packages/{name}/un-abandon",
+     *      name="unabandon_package",
+     *      requirements={"name"="[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+?"}
+     * )
+     */
+    public function unabandonAction($name)
+    {
+        /** @var $packageRepo \Packagist\WebBundle\Entity\PackageRepository */
+        $packageRepo = $this->getDoctrine()->getRepository('PackagistWebBundle:Package');
+
+        /** @var $package Package */
+        $package = $packageRepo->findOneByName($name);
+
+        if (!$package) {
+            throw $this->createNotFoundException("The requested package, $name, could not be found.");
+        }
+
+        if (!$package->getMaintainers()->contains($this->getUser()) && !$this->get('security.context')->isGranted('ROLE_EDIT_PACKAGES')) {
+            throw new AccessDeniedException;
+        }
+
+        $package->setAbandoned(false);
+        $package->setReplacementPackage(null);
+
+        $em = $this->getDoctrine()->getManager();
+        $em->persist($package);
+        $em->flush();
+
+        return $this->redirect($this->generateUrl('view_package', array('name' => $package->getName())));
+    }
 }
 

+ 44 - 0
src/Packagist/WebBundle/Entity/Package.php

@@ -112,6 +112,18 @@ class Package
      */
     private $autoUpdated = false;
 
+    /**
+     * @var bool
+     * @ORM\Column(type="boolean")
+     */
+    private $abandoned = false;
+
+    /**
+     * @var string
+     * @ORM\Column(type="string", length=255, nullable=true)
+     */
+    private $replacementPackage;
+
     /**
      * @ORM\Column(type="boolean", options={"default"=false})
      */
@@ -572,4 +584,36 @@ class Package
     {
         return $this->updateFailureNotified;
     }
+
+    /**
+     * @return boolean
+     */
+    public function isAbandoned()
+    {
+        return $this->abandoned;
+    }
+
+    /**
+     * @param boolean $abandoned
+     */
+    public function setAbandoned($abandoned)
+    {
+        $this->abandoned = $abandoned;
+    }
+
+    /**
+     * @return string
+     */
+    public function getReplacementPackage()
+    {
+        return $this->replacementPackage;
+    }
+
+    /**
+     * @param string $replacementPackage
+     */
+    public function setReplacementPackage($replacementPackage)
+    {
+        $this->replacementPackage = $replacementPackage;
+    }
 }

+ 51 - 0
src/Packagist/WebBundle/Form/Type/AbandonedType.php

@@ -0,0 +1,51 @@
+<?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 Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+
+/**
+ * Class AbandonedType
+ *
+ * Form used to acquire replacement Package information for abandoned package.
+ *
+ * @package Packagist\WebBundle\Form\Type
+ */
+class AbandonedType extends AbstractType
+{
+    /**
+     * @param FormBuilderInterface $builder
+     * @param array $options
+     */
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder->add(
+            'replacement',
+            'text',
+            array(
+                'required' => false,
+                'label'    => 'Replacement package',
+                'attr'     => array('placeholder' => 'optional')
+            )
+        );
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return 'package';
+    }
+}

+ 15 - 0
src/Packagist/WebBundle/Resources/public/css/main.css

@@ -337,6 +337,13 @@ ul.packages .metadata {
   padding-top: 8px;
 }
 
+ul.packages .abandoned {
+  float: right;
+  color: #800;
+  font-size: 12px;
+  margin-right: 10px;
+}
+
 ul.packages li {
     background: none repeat scroll 0 0 #EEEEEE;
     border: 1px solid #BBBBBB;
@@ -655,6 +662,14 @@ form ul {
   background: -ms-linear-gradient(top, #a61c1c 0%, #b84949 100%);
   background: linear-gradient(top, #a61c1c 0%, #b84949 100%);
 }
+.package .action.abandon input, .package .action.un-abandon input {
+  background: #ec400b;
+  background: -moz-linear-gradient(top, #ec400b 0%, #f5813f 100%);
+  background: -webkit-linear-gradient(top, #ec400b 0%, #f5813f 100%);
+  background: -o-linear-gradient(top, #ec400b 0%, #f5813f 100%);
+  background: -ms-linear-gradient(top, #ec400b 0%, #f5813f 100%);
+  background: linear-gradient(top, #ec400b 0%, #f5813f 100%);
+}
 .package .action.delete-version {
   float: none;
   display: inline-block;

+ 28 - 0
src/Packagist/WebBundle/Resources/views/Package/abandon.html.twig

@@ -0,0 +1,28 @@
+{% extends "PackagistWebBundle::layout.html.twig" %}
+
+{% block title %}{{ package.name }} - {{ parent() }}{% endblock %}
+
+{% block content %}
+    <div class="box">
+        <div class="package">
+            <h1>
+                {% if is_favorite is defined %}
+                    <i class="mark-favorite icon-star{% if not is_favorite %}-empty{% endif %}" data-remove-url="{{ path('user_remove_fav', {name: app.user.username, package: package.name}) }}" data-add-url="{{ path('user_add_fav', {name: app.user.username}) }}" data-package="{{ package.name }}"></i>
+                {% endif %}
+                <a href="{{ path("view_vendor", {"vendor": package.vendor}) }}">{{ package.vendor }}/</a>{{ package.packageName }}
+                <a id="copy" data-clipboard-text="{{ package.name }}" title="Copy to clipboard"><i class="icon-copy"></i></a>
+            </h1>
+
+            <p>You are about to mark this package as abandoned. This will alert users that this package will no longer be maintained.</p>
+            <p>If you are handing this project over to a new maintainer or know of a package that replaces it, please use
+                the field below to point users to the new package. In case you cannot point them to a new package, this one
+                will be tagged as abandoned and a replacement can be added later.</p>
+
+            <form method="post" {{ form_enctype(form) }}>
+                {{ form_widget(form) }}
+
+                <input type="submit" value="Abandon Package" />
+            </form>
+        </div>
+    </div>
+{% endblock %}

+ 21 - 0
src/Packagist/WebBundle/Resources/views/Web/viewPackage.html.twig

@@ -15,6 +15,7 @@
 {% block content %}
     <div class="box">
         <div class="package"{% if app.user and package.crawledAt is null and (is_granted('ROLE_EDIT_PACKAGES') or package.maintainers.contains(app.user)) %} data-force-crawl="true"{% endif %}>
+
             {% if is_granted('ROLE_EDIT_PACKAGES') or package.maintainers.contains(app.user) %}
                 <form class="action" action="{{ path("edit_package", {name: package.name}) }}">
                     <input type="submit" value="Edit" />
@@ -34,6 +35,16 @@
                     <input type="submit" value="Delete" />
                 </form>
             {% endif %}
+            {% if is_granted('ROLE_EDIT_PACKAGES') or package.maintainers.contains(app.user) and not package.abandoned %}
+                <form class="action abandon" action="{{ path('abandon_package', {name: package.name}) }}">
+                    <input type="submit" value="Abandon" />
+                </form>
+            {% endif %}
+            {% if is_granted('ROLE_EDIT_PACKAGES') or package.maintainers.contains(app.user) and package.abandoned %}
+                <form class="action un-abandon" action="{{ path('unabandon_package', {name: package.name}) }}">
+                    <input type="submit" value="Un-abandon" />
+                </form>
+            {% endif %}
             <h1>
                 {% if is_favorite is defined %}
                     <i class="mark-favorite icon-star{% if not is_favorite %}-empty{% endif %}" data-remove-url="{{ path('user_remove_fav', {name: app.user.username, package: package.name}) }}" data-add-url="{{ path('user_add_fav', {name: app.user.username}) }}" data-package="{{ package.name }}"></i>
@@ -56,6 +67,16 @@
                 <p class="warning">This package is not auto-updated. Go and set up the <a href="{{ path('fos_user_profile_show') }}">GitHub Service Hook</a> for Packagist so that it gets updated whenever you push!</p>
             {% endif %}
 
+            {% if package.abandoned %}
+                <p class="warning">
+                    This package is <strong>abandoned</strong> and no longer maintained.
+                    {% if package.replacementPackage is not empty %}
+                        The author suggests using the <a href="{{ path('view_package', {name: package.replacementPackage}) }}">{{ package.replacementPackage }}</a> package instead.
+                    {% else %}
+                        No replacement package was suggested.
+                    {% endif %}
+                </p>
+            {% endif %}
             {% if package.updateFailureNotified
                 and app.user and (package.maintainers.contains(app.user) or is_granted('ROLE_UPDATE_PACKAGES'))
             %}

+ 6 - 0
src/Packagist/WebBundle/Resources/views/macros.html.twig

@@ -22,9 +22,15 @@
                         [Not auto-updated]
                     {% endif %}
                 </h1>
+                {% if package.abandoned %}
+                <span class="abandoned">
+                    <i class="icon-warning-sign"></i> Abandoned! {% if package.replacementPackage is not empty %}Use: <a href="{{ path('view_package', {name: package.replacementPackage}) }}">{{ package.replacementPackage }}</a>{% endif %}
+                </span>
+                {% endif %}
                 {% if package.description is defined and package.description %}
                     <p class="package-description">{{ package.description }}</p>
                 {% endif %}
+
             </li>
         {% endfor %}