Ver código fonte

Remove all solr related code

Jordi Boggiano 7 anos atrás
pai
commit
bcc2e7ca27

+ 2 - 13
README.md

@@ -3,12 +3,13 @@ Packagist
 
 Package Repository Website for Composer, see the [about page](http://packagist.org/about) on [packagist.org](http://packagist.org/) for more.
 
+This project is not meant for re-use. It is open source to make it easy to contribute but we provide no support if you want to run your own, and will do breaking changes without notice.
+
 Requirements
 ------------
 
 - MySQL for the main data store
 - Redis for some functionality (favorites, download statistics)
-- Solr for search
 - git/svn/hg depending on which repositories you want to support
 
 Installation
@@ -24,18 +25,6 @@ Installation
 
 You should now be able to access the site, create a user, etc.
 
-Setting up search
------------------
-
-The search index uses [Solr](http://lucene.apache.org/solr/) 3.6, so you will have to install that on your server.
-If you are running it on a non-standard host or port, you will have to adjust the configuration. See the
-[NelmioSolariumBundle](https://github.com/nelmio/NelmioSolariumBundle) for more details.
-
-You will also have to configure Solr. Use the `schema.xml` provided in the doc/ directory for that.
-
-To index packages, just run `app/console packagist:index`. It is recommended to set up a cron job for
-this command, and have it run every few minutes.
-
 Day-to-Day Operation
 --------------------
 

+ 0 - 1
app/AppKernel.php

@@ -21,7 +21,6 @@ class AppKernel extends Kernel
             new HWI\Bundle\OAuthBundle\HWIOAuthBundle(),
             new Snc\RedisBundle\SncRedisBundle(),
             new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),
-            new Nelmio\SolariumBundle\NelmioSolariumBundle(),
             new Nelmio\SecurityBundle\NelmioSecurityBundle(),
             new Knp\Bundle\MenuBundle\KnpMenuBundle(),
             new Nelmio\CorsBundle\NelmioCorsBundle(),

+ 0 - 8
app/config/config.yml

@@ -112,14 +112,6 @@ hwi_oauth:
             options:
                 csrf: true
 
-nelmio_solarium:
-    clients:
-        default:
-            host: '%solr_host%'
-            port: '%solr_port%'
-            path: '%solr_path%'
-            core: '%solr_core%'
-
 nelmio_cors:
     defaults:
         allow_origin: ['*']

+ 0 - 4
app/config/defaults.yml

@@ -6,8 +6,4 @@ parameters:
     database_name_test: packagist_test
     redis_dsn_test: redis://127.0.0.1/14
     assets_version: 1234
-    solr_host: 127.0.0.1
-    solr_port: 8983
-    solr_path: /solr
-    solr_core: collection1
     trusted_ip_header: ''

+ 0 - 5
app/config/parameters.yml.dist

@@ -21,11 +21,6 @@ parameters:
     redis_dsn_test: redis://127.0.0.1/14
     redis_session_dsn: redis://localhost/2
 
-    solr_host: 127.0.0.1
-    solr_port: 8983
-    solr_path: /solr
-    solr_core: collection1
-
     locale: en
 
     google_analytics:

+ 0 - 1
composer.json

@@ -42,7 +42,6 @@
         "composer/composer": "^1.3@dev",
         "friendsofsymfony/user-bundle": "^2.0@dev",
         "hwi/oauth-bundle": "^0.4",
-        "nelmio/solarium-bundle": "^1.0",
         "nelmio/security-bundle": "^1.0",
         "predis/predis": "^1.0",
         "snc/redis-bundle": "^2.0",

+ 1 - 98
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "content-hash": "3997486ee7be835942f6cf3161f38fbb",
+    "content-hash": "d66a4039537323b09a560472fe93c122",
     "packages": [
         {
             "name": "algolia/algoliasearch-client-php",
@@ -2272,61 +2272,6 @@
             ],
             "time": "2016-02-23T10:42:13+00:00"
         },
-        {
-            "name": "nelmio/solarium-bundle",
-            "version": "v1.1.0",
-            "target-dir": "Nelmio/SolariumBundle",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/nelmio/NelmioSolariumBundle.git",
-                "reference": "693700c4deeb04997b90aca659dd881409f33eb9"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/nelmio/NelmioSolariumBundle/zipball/693700c4deeb04997b90aca659dd881409f33eb9",
-                "reference": "693700c4deeb04997b90aca659dd881409f33eb9",
-                "shasum": ""
-            },
-            "require": {
-                "solarium/solarium": "~2.4.0",
-                "symfony/framework-bundle": "2.*"
-            },
-            "require-dev": {
-                "symfony/yaml": "2.*"
-            },
-            "type": "symfony-bundle",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.1-dev"
-                }
-            },
-            "autoload": {
-                "psr-0": {
-                    "Nelmio\\SolariumBundle": ""
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nelmio",
-                    "homepage": "http://nelm.io"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://github.com/nelmio/NelmioSolariumBundle/contributors"
-                }
-            ],
-            "description": "Integration with solarium solr client.",
-            "keywords": [
-                "search",
-                "solarium",
-                "solr"
-            ],
-            "time": "2013-01-07T10:35:43+00:00"
-        },
         {
             "name": "pagerfanta/pagerfanta",
             "version": "v1.0.3",
@@ -2993,48 +2938,6 @@
             ],
             "time": "2016-06-17T11:50:26+00:00"
         },
-        {
-            "name": "solarium/solarium",
-            "version": "2.4.1",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/solariumphp/solarium.git",
-                "reference": "f7c55cf42d14bb70f534128da3e343bb98fcb504"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/solariumphp/solarium/zipball/f7c55cf42d14bb70f534128da3e343bb98fcb504",
-                "reference": "f7c55cf42d14bb70f534128da3e343bb98fcb504",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.2.0"
-            },
-            "type": "library",
-            "autoload": {
-                "psr-0": {
-                    "Solarium": "library/"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "NewBSD"
-            ],
-            "authors": [
-                {
-                    "name": "See GitHub contributors",
-                    "homepage": "https://github.com/basdenooijer/solarium/contributors"
-                }
-            ],
-            "description": "PHP Solr client",
-            "homepage": "http://www.solarium-project.org",
-            "keywords": [
-                "php",
-                "search",
-                "solr"
-            ],
-            "time": "2013-02-11T13:12:43+00:00"
-        },
         {
             "name": "swiftmailer/swiftmailer",
             "version": "v5.4.5",

+ 0 - 282
doc/schema.xml

@@ -1,282 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<schema name="packagist" version="1.4">
-  <types>
-    <!-- The StrField type is not analyzed, but indexed/stored verbatim. -->
-    <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
-    <!-- boolean type: "true" or "false" -->
-    <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/>
-    <!--Binary data type. The data should be sent/retrieved in as Base64 encoded Strings -->
-    <fieldtype name="binary" class="solr.BinaryField"/>
-
-    <!-- The optional sortMissingLast and sortMissingFirst attributes are
-         currently supported on types that are sorted internally as strings
-         and on numeric types.
-	       This includes "string","boolean", and, as of 3.5 (and 4.x),
-	       int, float, long, date, double, including the "Trie" variants.
-       - If sortMissingLast="true", then a sort on this field will cause documents
-         without the field to come after documents with the field,
-         regardless of the requested sort order (asc or desc).
-       - If sortMissingFirst="true", then a sort on this field will cause documents
-         without the field to come before documents with the field,
-         regardless of the requested sort order.
-       - If sortMissingLast="false" and sortMissingFirst="false" (the default),
-         then default lucene sorting will be used which places docs without the
-         field first in an ascending sort and last in a descending sort.
-    -->
-
-    <fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
-    <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
-    <fieldType name="long" class="solr.TrieLongField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
-    <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
-
-    <fieldType name="date" class="solr.TrieDateField" omitNorms="true" precisionStep="0" positionIncrementGap="0"/>
-
-    <!-- A Trie based date field for faster date range queries and date faceting. -->
-    <fieldType name="tdate" class="solr.TrieDateField" omitNorms="true" precisionStep="6" positionIncrementGap="0"/>
-
-    <!-- A edge-ngram'd text field that can be used for wildcard matching -->
-    <fieldType name="text_edgengram" class="solr.TextField" positionIncrementGap="100">
-        <analyzer type="index">
-            <tokenizer class="solr.StandardTokenizerFactory"/>
-            <filter class="solr.WordDelimiterFilterFactory" splitOnCaseChange="1" generateWordParts="1" preserveOriginal="1"/>
-            <filter class="solr.LowerCaseFilterFactory"/>
-            <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="100" />
-        </analyzer>
-        <analyzer type="query">
-            <tokenizer class="solr.WhitespaceTokenizerFactory"/>
-            <filter class="solr.LowerCaseFilterFactory"/>
-        </analyzer>
-    </fieldType>
-
-    <!-- A general text field that has reasonable, generic
-         cross-language defaults: it tokenizes with StandardTokenizer,
-	 removes stop words from case-insensitive "stopwords.txt"
-	 (empty by default), and down cases.  At query time only, it
-	 also applies synonyms. -->
-    <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
-      <analyzer type="index">
-        <tokenizer class="solr.StandardTokenizerFactory"/>
-        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
-        <filter class="solr.LowerCaseFilterFactory"/>
-      </analyzer>
-      <analyzer type="query">
-        <tokenizer class="solr.StandardTokenizerFactory"/>
-        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
-        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
-        <filter class="solr.LowerCaseFilterFactory"/>
-      </analyzer>
-    </fieldType>
-
-    <!-- Just like text_general except it reverses the characters of
-	 each token, to enable more efficient leading wildcard queries. -->
-    <fieldType name="text_general_rev" class="solr.TextField" positionIncrementGap="100">
-      <analyzer type="index">
-        <tokenizer class="solr.StandardTokenizerFactory"/>
-        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
-        <filter class="solr.LowerCaseFilterFactory"/>
-        <filter class="solr.ReversedWildcardFilterFactory" withOriginal="true"
-           maxPosAsterisk="3" maxPosQuestion="2" maxFractionAsterisk="0.33"/>
-      </analyzer>
-      <analyzer type="query">
-        <tokenizer class="solr.StandardTokenizerFactory"/>
-        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
-        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
-        <filter class="solr.LowerCaseFilterFactory"/>
-      </analyzer>
-    </fieldType>
-
-    <!-- A text field with defaults appropriate for English: it
-         tokenizes with StandardTokenizer, removes English stop words
-         (lang/stopwords_en.txt), down cases, protects words from protwords.txt, and
-         finally applies Porter's stemming.  The query time analyzer
-         also applies synonyms from synonyms.txt. -->
-    <fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
-      <analyzer type="index">
-        <tokenizer class="solr.StandardTokenizerFactory"/>
-        <!-- in this example, we will only use synonyms at query time
-        <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
-        -->
-        <!-- Case insensitive stop word removal.
-          add enablePositionIncrements=true in both the index and query
-          analyzers to leave a 'gap' for more accurate phrase queries.
-        -->
-        <filter class="solr.StopFilterFactory"
-                ignoreCase="true"
-                words="lang/stopwords_en.txt"
-                enablePositionIncrements="true"
-                />
-        <filter class="solr.LowerCaseFilterFactory"/>
-        <filter class="solr.EnglishPossessiveFilterFactory"/>
-        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-	<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
-        <filter class="solr.EnglishMinimalStemFilterFactory"/>
-	-->
-        <filter class="solr.PorterStemFilterFactory"/>
-      </analyzer>
-      <analyzer type="query">
-        <tokenizer class="solr.StandardTokenizerFactory"/>
-        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
-        <filter class="solr.StopFilterFactory"
-                ignoreCase="true"
-                words="lang/stopwords_en.txt"
-                enablePositionIncrements="true"
-                />
-        <filter class="solr.LowerCaseFilterFactory"/>
-        <filter class="solr.EnglishPossessiveFilterFactory"/>
-        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-	<!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
-        <filter class="solr.EnglishMinimalStemFilterFactory"/>
-	-->
-        <filter class="solr.PorterStemFilterFactory"/>
-      </analyzer>
-    </fieldType>
-
-    <!-- A text field with defaults appropriate for English, plus
-	 aggressive word-splitting and autophrase features enabled.
-	 This field is just like text_en, except it adds
-	 WordDelimiterFilter to enable splitting and matching of
-	 words on case-change, alpha numeric boundaries, and
-	 non-alphanumeric chars.  This means certain compound word
-	 cases will work, for example query "wi fi" will match
-	 document "WiFi" or "wi-fi".  However, other cases will still
-	 not match, for example if the query is "wifi" and the
-	 document is "wi fi" or if the query is "wi-fi" and the
-	 document is "wifi".
-        -->
-    <fieldType name="text_en_splitting" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
-      <analyzer type="index">
-        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
-        <!-- in this example, we will only use synonyms at query time
-        <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
-        -->
-        <!-- Case insensitive stop word removal.
-          add enablePositionIncrements=true in both the index and query
-          analyzers to leave a 'gap' for more accurate phrase queries.
-        -->
-        <filter class="solr.StopFilterFactory"
-                ignoreCase="true"
-                words="lang/stopwords_en.txt"
-                enablePositionIncrements="true"
-                />
-        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
-        <filter class="solr.LowerCaseFilterFactory"/>
-        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-        <filter class="solr.PorterStemFilterFactory"/>
-      </analyzer>
-      <analyzer type="query">
-        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
-        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
-        <filter class="solr.StopFilterFactory"
-                ignoreCase="true"
-                words="lang/stopwords_en.txt"
-                enablePositionIncrements="true"
-                />
-        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
-        <filter class="solr.LowerCaseFilterFactory"/>
-        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-        <filter class="solr.PorterStemFilterFactory"/>
-      </analyzer>
-    </fieldType>
-
-    <!-- Less flexible matching, but less false matches.  Probably not ideal for product names,
-         but may be good for SKUs.  Can insert dashes in the wrong place and still match. -->
-    <fieldType name="text_en_splitting_tight" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
-      <analyzer>
-        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
-        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
-        <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt"/>
-        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
-        <filter class="solr.LowerCaseFilterFactory"/>
-        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
-        <filter class="solr.EnglishMinimalStemFilterFactory"/>
-        <!-- this filter can remove any duplicate tokens that appear at the same position - sometimes
-             possible with WordDelimiterFilter in conjuncton with stemming. -->
-        <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
-      </analyzer>
-    </fieldType>
-
-    <fieldtype name="phonetic" stored="false" indexed="true" class="solr.TextField" >
-      <analyzer>
-        <tokenizer class="solr.StandardTokenizerFactory"/>
-        <filter class="solr.DoubleMetaphoneFilterFactory" inject="false"/>
-      </analyzer>
-    </fieldtype>
-
-    <!-- since fields of this type are by default not stored or indexed,
-         any data added to them will be ignored outright.  -->
-    <fieldtype name="ignored" stored="false" indexed="false" multiValued="true" class="solr.StrField" />
- </types>
-
- <fields>
-   <!-- Valid attributes for fields:
-     name: mandatory - the name for the field
-     type: mandatory - the name of a previously defined type from the
-       <types> section
-     indexed: true if this field should be indexed (searchable or sortable)
-     stored: true if this field should be retrievable
-     multiValued: true if this field may contain multiple values per document
-     omitNorms: (expert) set to true to omit the norms associated with
-       this field (this disables length normalization and index-time
-       boosting for the field, and saves some memory).  Only full-text
-       fields or fields that need an index-time boost need norms.
-     termVectors: [false] set to true to store the term vector for a
-       given field.
-       When using MoreLikeThis, fields used for similarity should be
-       stored for best performance.
-     termPositions: Store position information with the term vector.
-       This will increase storage costs.
-     termOffsets: Store offset information with the term vector. This
-       will increase storage costs.
-     default: a value that should be used if no value is specified
-       when adding a document.
-   -->
-
-   <field name="id" type="string" indexed="true" stored="true" required="true" />
-   <field name="name" type="text_general_rev" indexed="true" stored="true"/>
-   <field name="description" type="text_general_rev" indexed="true" stored="true"/>
-   <field name="tags" type="text_general_rev" indexed="true" stored="true" multiValued="true"/>
-   <field name="type" type="text_general_rev" indexed="true" stored="true"/>
-   <field name="trendiness" type="float" indexed="true" stored="true" />
-   <field name="downloads" type="int" indexed="true" stored="true" />
-   <field name="favers" type="int" indexed="true" stored="true" />
-   <field name="language" type="string" indexed="true" stored="true" />
-   <field name="repository" type="string" indexed="false" stored="true" />
-   <field name="abandoned" type="int" indexed="false" stored="true" />
-   <field name="replacementPackage" type="string" indexed="false" stored="true" />
-
-   <!-- catchall field, containing all other searchable text fields (implemented
-        via copyField further on in this schema  -->
-   <field name="text" type="text_en" indexed="true" stored="false" multiValued="true"/>
-
-   <!-- extra name field allowing dashes to be omitted/misplaced -->
-   <field name="name_split" type="text_en_splitting_tight" indexed="true" stored="false" />
-   <!-- extra name field allowing dashes to be omitted/misplaced and containing no vendor prefix -->
-   <field name="package_name" type="text_en_splitting_tight" indexed="true" stored="false" />
-
-   <!-- extra catchall for ngram searches -->
-   <field name="text_ngram" type="text_edgengram" indexed="true" stored="false" multiValued="true" />
- </fields>
-
- <!-- Field to use to determine and enforce document uniqueness.
-      Unless this field is marked with required="false", it will be a required field
-   -->
- <uniqueKey>id</uniqueKey>
-
- <!-- field for the QueryParser to use when an explicit fieldname is absent -->
- <defaultSearchField>text</defaultSearchField>
-
- <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->
- <solrQueryParser defaultOperator="OR"/>
-  <!-- copyField commands copy one field to another at the time a document
-        is added to the index.  It's used either to index the same field differently,
-        or to add multiple fields to the same field for easier/faster searching.  -->
-
-   <copyField source="name" dest="text"/>
-   <copyField source="description" dest="text"/>
-   <copyField source="tags" dest="text"/>
-
-   <copyField source="name" dest="name_split"/>
-
-   <copyField source="name" dest="text_ngram"/>
-   <copyField source="tags" dest="text_ngram"/>
-</schema>

+ 0 - 46
doc/solrconfig.xml

@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!--
- This is a stripped down config file used for a simple example...
- It is *not* a good example to work from.
--->
-<config>
-  <luceneMatchVersion>LUCENE_36</luceneMatchVersion>
-  <!--  The DirectoryFactory to use for indexes.
-        solr.StandardDirectoryFactory, the default, is filesystem based.
-        solr.RAMDirectoryFactory is memory based, not persistent, and doesn't work with replication. -->
-  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
-
-
-  <updateHandler class="solr.DirectUpdateHandler2" />
-
-  <requestDispatcher handleSelect="true" >
-    <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" />
-  </requestDispatcher>
-
-  <requestHandler name="standard" class="solr.StandardRequestHandler" default="true" />
-  <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" />
-  <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
-
-  <!-- config for the admin interface -->
-  <admin>
-    <defaultQuery>solr</defaultQuery>
-  </admin>
-
-</config>

+ 0 - 289
src/Packagist/WebBundle/Command/IndexAlgoliaPackagesCommand.php

@@ -1,289 +0,0 @@
-<?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\Command;
-
-use Packagist\WebBundle\Entity\Package;
-use Packagist\WebBundle\Model\DownloadManager;
-use Packagist\WebBundle\Model\FavoriteManager;
-use Solarium_Document_ReadWrite;
-use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Input\InputOption;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Filesystem\LockHandler;
-use Doctrine\DBAL\Connection;
-
-class IndexAlgoliaPackagesCommand extends ContainerAwareCommand
-{
-    /**
-     * {@inheritdoc}
-     */
-    protected function configure()
-    {
-        $this
-            ->setName('algolia:index')
-            ->setDefinition(array(
-                new InputOption('force', null, InputOption::VALUE_NONE, 'Force a re-indexing of all packages'),
-                new InputOption('all', null, InputOption::VALUE_NONE, 'Index all packages without clearing the index first'),
-                new InputArgument('package', InputArgument::OPTIONAL, 'Package name to index'),
-            ))
-            ->setDescription('Indexes packages in Algolia')
-        ;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function execute(InputInterface $input, OutputInterface $output)
-    {
-        $verbose = $input->getOption('verbose');
-        $force = $input->getOption('force');
-        $indexAll = $input->getOption('all');
-        $package = $input->getArgument('package');
-        $indexName = $this->getContainer()->getParameter('algolia.index_name');
-
-        $deployLock = $this->getContainer()->getParameter('kernel.cache_dir').'/deploy.globallock';
-        if (file_exists($deployLock)) {
-            if ($verbose) {
-                $output->writeln('Aborting, '.$deployLock.' file present');
-            }
-            return;
-        }
-
-        $doctrine = $this->getContainer()->get('doctrine');
-        $algolia = $this->getContainer()->get('packagist.algolia.client');
-        $index = $algolia->initIndex($indexName);
-
-        $redis = $this->getContainer()->get('snc_redis.default');
-        $downloadManager = $this->getContainer()->get('packagist.download_manager');
-        $favoriteManager = $this->getContainer()->get('packagist.favorite_manager');
-
-        $lock = new LockHandler('packagist_algolia_indexer');
-
-        // another dumper is still active
-        if (!$lock->lock()) {
-            if ($verbose) {
-                $output->writeln('Aborting, another indexer is still active');
-            }
-            return;
-        }
-
-        if ($package) {
-            $packages = array(array('id' => $doctrine->getRepository('PackagistWebBundle:Package')->findOneByName($package)->getId()));
-        } elseif ($force || $indexAll) {
-            $packages = $doctrine->getManager()->getConnection()->fetchAll('SELECT id FROM package ORDER BY id ASC');
-            $doctrine->getManager()->getConnection()->executeQuery('UPDATE package SET indexedAt = NULL');
-        } else {
-            $packages = $doctrine->getRepository('PackagistWebBundle:Package')->getStalePackagesForIndexing();
-        }
-
-        $ids = array();
-        foreach ($packages as $row) {
-            $ids[] = $row['id'];
-        }
-
-        // clear index before a full-update
-        if ($force && !$package) {
-            if ($verbose) {
-                $output->writeln('Deleting existing index');
-            }
-
-            $index->clearIndex();
-        }
-
-        $total = count($ids);
-        $current = 0;
-
-        // update package index
-        while ($ids) {
-            $indexTime = new \DateTime;
-            $idsSlice = array_splice($ids, 0, 50);
-            $packages = $doctrine->getRepository('PackagistWebBundle:Package')->findById($idsSlice);
-
-            $idsToUpdate = [];
-            $records = [];
-
-            foreach ($packages as $package) {
-                $current++;
-                if ($verbose) {
-                    $output->writeln('['.sprintf('%'.strlen($total).'d', $current).'/'.$total.'] Indexing '.$package->getName());
-                }
-
-                try {
-                    $tags = $this->getTags($doctrine, $package);
-
-                    $records[] = $this->packageToSearchableArray($package, $tags, $redis, $downloadManager, $favoriteManager);
-
-                    $idsToUpdate[] = $package->getId();
-                } catch (\Exception $e) {
-                    $output->writeln('<error>Exception: '.$e->getMessage().', skipping package '.$package->getName().'.</error>');
-
-                    continue;
-                }
-
-                $providers = $this->getProviders($doctrine, $package);
-                foreach ($providers as $provided) {
-                    $records[] = $this->createSearchableProvider($provided['packageName']);
-                }
-            }
-
-            try {
-                $index->addObjects($records);
-            } catch (\Exception $e) {
-                $output->writeln('<error>'.get_class($e).': '.$e->getMessage().', occurred while processing packages: '.implode(',', $idsSlice).'</error>');
-                continue;
-            }
-
-            $doctrine->getManager()->clear();
-            unset($packages);
-
-            if ($verbose) {
-                $output->writeln('Updating package indexedAt column');
-            }
-
-            $this->updateIndexedAt($idsToUpdate, $doctrine, $indexTime->format('Y-m-d H:i:s'));
-        }
-
-        $lock->release();
-    }
-
-    private function packageToSearchableArray(
-        Package $package,
-        array $tags,
-        $redis,
-        DownloadManager $downloadManager,
-        FavoriteManager $favoriteManager
-    ) {
-        $faversCount = $favoriteManager->getFaverCount($package);
-        $downloads = $downloadManager->getDownloads($package);
-        $downloadsLog = $downloads['monthly'] > 0 ? log($downloads['monthly'], 10) : 0;
-        $starsLog = $package->getGitHubStars() > 0 ? log($package->getGitHubStars(), 10) : 0;
-        $popularity = round($downloadsLog + $starsLog);
-        $trendiness = $redis->zscore('downloads:trending', $package->getId());
-
-        $record = [
-            'id' => $package->getId(),
-            'objectID' => $package->getName(),
-            'name' => $package->getName(),
-            'package_organisation' => $package->getVendor(),
-            'package_name' => $package->getPackageName(),
-            'description' => preg_replace('{[\x00-\x1f]+}u', '', strip_tags($package->getDescription())),
-            'type' => $package->getType(),
-            'repository' => $package->getRepository(),
-            'language' => $package->getLanguage(),
-            # log10 of downloads over the last 7days
-            'trendiness' => $trendiness > 0 ? log($trendiness, 10) : 0,
-            # log10 of downloads + gh stars
-            'popularity' => $popularity,
-            'meta' => [
-                'downloads' => $downloads['total'],
-                'downloads_formatted' => number_format($downloads['total'], 0, ',', ' '),
-                'favers' => $faversCount,
-                'favers_formatted' => number_format($faversCount, 0, ',', ' '),
-            ],
-        ];
-
-        if ($package->isAbandoned()) {
-            $record['abandoned'] = 1;
-            $record['replacementPackage'] = $package->getReplacementPackage() ?: '';
-        } else {
-            $record['abandoned'] = 0;
-            $record['replacementPackage'] = '';
-        }
-
-        $record['tags'] = $tags;
-
-        return $record;
-    }
-
-    private function createSearchableProvider(string $provided)
-    {
-        $record = [
-            'id' => $provided,
-            'objectID' => $provided,
-            'name' => $provided,
-            'package_organisation' => preg_replace('{/.*$}', '', $provided),
-            'package_name' => preg_replace('{^[^/]*/}', '', $provided),
-            'description' => '',
-            'type' => 'virtual-package',
-            'repository' => '',
-            'language' => '',
-            'trendiness' => 100,
-            'popularity' => 4,
-            'abandoned' => 0,
-            'replacementPackage' => '',
-            'tags' => [],
-        ];
-
-        return $record;
-    }
-
-    private function getProviders($doctrine, Package $package)
-    {
-        return $doctrine->getManager()->getConnection()->fetchAll(
-            'SELECT lp.packageName
-                FROM package p
-                JOIN package_version pv ON p.id = pv.package_id
-                JOIN link_provide lp ON lp.version_id = pv.id
-                WHERE p.id = :id
-                AND pv.development = true
-                GROUP BY lp.packageName',
-            ['id' => $package->getId()]
-        );
-    }
-
-    private function getTags($doctrine, Package $package)
-    {
-        $tags = $doctrine->getManager()->getConnection()->fetchAll(
-            'SELECT t.name FROM package p
-                            JOIN package_version pv ON p.id = pv.package_id
-                            JOIN version_tag vt ON vt.version_id = pv.id
-                            JOIN tag t ON t.id = vt.tag_id
-                            WHERE p.id = :id
-                            GROUP BY t.id, t.name',
-            ['id' => $package->getId()]
-        );
-
-        foreach ($tags as $idx => $tag) {
-            $tags[$idx] = $tag['name'];
-        }
-
-        return array_map(function ($tag) {
-            return mb_strtolower(preg_replace('{[\x00-\x1f]+}u', '', $tag), 'UTF-8');
-        }, $tags);
-    }
-
-    private function updateIndexedAt(array $idsToUpdate, $doctrine, string $time)
-    {
-        $retries = 5;
-        // retry loop in case of a lock timeout
-        while ($retries--) {
-            try {
-                $doctrine->getManager()->getConnection()->executeQuery(
-                    'UPDATE package SET indexedAt=:indexed WHERE id IN (:ids)',
-                    [
-                        'ids' => $idsToUpdate,
-                        'indexed' => $time,
-                    ],
-                    ['ids' => Connection::PARAM_INT_ARRAY]
-                );
-            } catch (\Exception $e) {
-                if (!$retries) {
-                    throw $e;
-                }
-                sleep(2);
-            }
-        }
-    }
-}

+ 132 - 95
src/Packagist/WebBundle/Command/IndexPackagesCommand.php

@@ -15,7 +15,6 @@ namespace Packagist\WebBundle\Command;
 use Packagist\WebBundle\Entity\Package;
 use Packagist\WebBundle\Model\DownloadManager;
 use Packagist\WebBundle\Model\FavoriteManager;
-use Solarium_Document_ReadWrite;
 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
@@ -24,9 +23,6 @@ use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Filesystem\LockHandler;
 use Doctrine\DBAL\Connection;
 
-/**
- * @author Igor Wiedler <igor@wiedler.ch>
- */
 class IndexPackagesCommand extends ContainerAwareCommand
 {
     /**
@@ -35,13 +31,13 @@ class IndexPackagesCommand extends ContainerAwareCommand
     protected function configure()
     {
         $this
-            ->setName('packagist:index')
+            ->setName('packcagist:index')
             ->setDefinition(array(
                 new InputOption('force', null, InputOption::VALUE_NONE, 'Force a re-indexing of all packages'),
                 new InputOption('all', null, InputOption::VALUE_NONE, 'Index all packages without clearing the index first'),
                 new InputArgument('package', InputArgument::OPTIONAL, 'Package name to index'),
             ))
-            ->setDescription('Indexes packages in Solr')
+            ->setDescription('Indexes packages in Algolia')
         ;
     }
 
@@ -54,6 +50,7 @@ class IndexPackagesCommand extends ContainerAwareCommand
         $force = $input->getOption('force');
         $indexAll = $input->getOption('all');
         $package = $input->getArgument('package');
+        $indexName = $this->getContainer()->getParameter('algolia.index_name');
 
         $deployLock = $this->getContainer()->getParameter('kernel.cache_dir').'/deploy.globallock';
         if (file_exists($deployLock)) {
@@ -64,12 +61,14 @@ class IndexPackagesCommand extends ContainerAwareCommand
         }
 
         $doctrine = $this->getContainer()->get('doctrine');
-        $solarium = $this->getContainer()->get('solarium.client');
+        $algolia = $this->getContainer()->get('packagist.algolia.client');
+        $index = $algolia->initIndex($indexName);
+
         $redis = $this->getContainer()->get('snc_redis.default');
         $downloadManager = $this->getContainer()->get('packagist.download_manager');
         $favoriteManager = $this->getContainer()->get('packagist.favorite_manager');
 
-        $lock = new LockHandler('packagist_package_indexer');
+        $lock = new LockHandler('packagist_algolia_indexer');
 
         // another dumper is still active
         if (!$lock->lock()) {
@@ -99,11 +98,7 @@ class IndexPackagesCommand extends ContainerAwareCommand
                 $output->writeln('Deleting existing index');
             }
 
-            $update = $solarium->createUpdate();
-            $update->addDeleteQuery('*:*');
-            $update->addCommit();
-
-            $solarium->update($update);
+            $index->clearIndex();
         }
 
         $total = count($ids);
@@ -114,9 +109,9 @@ class IndexPackagesCommand extends ContainerAwareCommand
             $indexTime = new \DateTime;
             $idsSlice = array_splice($ids, 0, 50);
             $packages = $doctrine->getRepository('PackagistWebBundle:Package')->findById($idsSlice);
-            $update = $solarium->createUpdate();
 
             $idsToUpdate = [];
+            $records = [];
 
             foreach ($packages as $package) {
                 $current++;
@@ -125,21 +120,9 @@ class IndexPackagesCommand extends ContainerAwareCommand
                 }
 
                 try {
-                    $document = $update->createDocument();
-                    $tags = $doctrine->getManager()->getConnection()->fetchAll(
-                        'SELECT t.name FROM package p
-                            JOIN package_version pv ON p.id = pv.package_id
-                            JOIN version_tag vt ON vt.version_id = pv.id
-                            JOIN tag t ON t.id = vt.tag_id
-                            WHERE p.id = :id
-                            GROUP BY t.id, t.name',
-                        ['id' => $package->getId()]
-                    );
-                    foreach ($tags as $idx => $tag) {
-                        $tags[$idx] = $tag['name'];
-                    }
-                    $this->updateDocumentFromPackage($document, $package, $tags, $redis, $downloadManager, $favoriteManager);
-                    $update->addDocument($document);
+                    $tags = $this->getTags($doctrine, $package);
+
+                    $records[] = $this->packageToSearchableArray($package, $tags, $redis, $downloadManager, $favoriteManager);
 
                     $idsToUpdate[] = $package->getId();
                 } catch (\Exception $e) {
@@ -148,39 +131,14 @@ class IndexPackagesCommand extends ContainerAwareCommand
                     continue;
                 }
 
-                $providers = $doctrine->getManager()->getConnection()->fetchAll(
-                    'SELECT lp.packageName
-                        FROM package p
-                        JOIN package_version pv ON p.id = pv.package_id
-                        JOIN link_provide lp ON lp.version_id = pv.id
-                        WHERE p.id = :id
-                        AND pv.development = true
-                        GROUP BY lp.packageName',
-                    ['id' => $package->getId()]
-                );
+                $providers = $this->getProviders($doctrine, $package);
                 foreach ($providers as $provided) {
-                    $provided = $provided['packageName'];
-                    try {
-                        $document = $update->createDocument();
-                        $document->setField('id', $provided);
-                        $document->setField('name', $provided);
-                        $document->setField('package_name', '');
-                        $document->setField('description', '');
-                        $document->setField('type', 'virtual-package');
-                        $document->setField('trendiness', 100);
-                        $document->setField('repository', '');
-                        $document->setField('abandoned', 0);
-                        $document->setField('replacementPackage', '');
-                        $update->addDocument($document);
-                    } catch (\Exception $e) {
-                        $output->writeln('<error>'.get_class($e).': '.$e->getMessage().', skipping package '.$package->getName().':provide:'.$provided.'</error>');
-                    }
+                    $records[] = $this->createSearchableProvider($provided['packageName']);
                 }
             }
 
             try {
-                $update->addCommit();
-                $solarium->update($update);
+                $index->addObjects($records);
             } catch (\Exception $e) {
                 $output->writeln('<error>'.get_class($e).': '.$e->getMessage().', occurred while processing packages: '.implode(',', $idsSlice).'</error>');
                 continue;
@@ -190,62 +148,141 @@ class IndexPackagesCommand extends ContainerAwareCommand
             unset($packages);
 
             if ($verbose) {
-                $output->writeln('Updating package index times');
+                $output->writeln('Updating package indexedAt column');
             }
 
-            $retries = 5;
-            // retry loop in case of a lock timeout
-            while ($retries--) {
-                try {
-                    $doctrine->getManager()->getConnection()->executeQuery(
-                        'UPDATE package SET indexedAt=:indexed WHERE id IN (:ids)',
-                        [
-                            'ids' => $idsToUpdate,
-                            'indexed' => $indexTime->format('Y-m-d H:i:s'),
-                        ],
-                        ['ids' => Connection::PARAM_INT_ARRAY]
-                    );
-                } catch (\Exception $e) {
-                    if (!$retries) {
-                        throw $e;
-                    }
-                    sleep(2);
-                }
-            }
+            $this->updateIndexedAt($idsToUpdate, $doctrine, $indexTime->format('Y-m-d H:i:s'));
         }
 
         $lock->release();
     }
 
-    private function updateDocumentFromPackage(
-        Solarium_Document_ReadWrite $document,
+    private function packageToSearchableArray(
         Package $package,
         array $tags,
         $redis,
         DownloadManager $downloadManager,
         FavoriteManager $favoriteManager
     ) {
-        $document->setField('id', $package->getId());
-        $document->setField('name', $package->getName());
-        $document->setField('package_name', $package->getPackageName());
-        $document->setField('description', preg_replace('{[\x00-\x1f]+}u', '', $package->getDescription()));
-        $document->setField('type', $package->getType());
-        $document->setField('trendiness', $redis->zscore('downloads:trending', $package->getId()));
-        $document->setField('downloads', $downloadManager->getTotalDownloads($package));
-        $document->setField('favers', $favoriteManager->getFaverCount($package));
-        $document->setField('repository', $package->getRepository());
-        $document->setField('language', $package->getLanguage());
+        $faversCount = $favoriteManager->getFaverCount($package);
+        $downloads = $downloadManager->getDownloads($package);
+        $downloadsLog = $downloads['monthly'] > 0 ? log($downloads['monthly'], 10) : 0;
+        $starsLog = $package->getGitHubStars() > 0 ? log($package->getGitHubStars(), 10) : 0;
+        $popularity = round($downloadsLog + $starsLog);
+        $trendiness = $redis->zscore('downloads:trending', $package->getId());
+
+        $record = [
+            'id' => $package->getId(),
+            'objectID' => $package->getName(),
+            'name' => $package->getName(),
+            'package_organisation' => $package->getVendor(),
+            'package_name' => $package->getPackageName(),
+            'description' => preg_replace('{[\x00-\x1f]+}u', '', strip_tags($package->getDescription())),
+            'type' => $package->getType(),
+            'repository' => $package->getRepository(),
+            'language' => $package->getLanguage(),
+            # log10 of downloads over the last 7days
+            'trendiness' => $trendiness > 0 ? log($trendiness, 10) : 0,
+            # log10 of downloads + gh stars
+            'popularity' => $popularity,
+            'meta' => [
+                'downloads' => $downloads['total'],
+                'downloads_formatted' => number_format($downloads['total'], 0, ',', ' '),
+                'favers' => $faversCount,
+                'favers_formatted' => number_format($faversCount, 0, ',', ' '),
+            ],
+        ];
+
         if ($package->isAbandoned()) {
-            $document->setField('abandoned', 1);
-            $document->setField('replacementPackage', $package->getReplacementPackage() ?: '');
+            $record['abandoned'] = 1;
+            $record['replacementPackage'] = $package->getReplacementPackage() ?: '';
         } else {
-            $document->setField('abandoned', 0);
-            $document->setField('replacementPackage', '');
+            $record['abandoned'] = 0;
+            $record['replacementPackage'] = '';
+        }
+
+        $record['tags'] = $tags;
+
+        return $record;
+    }
+
+    private function createSearchableProvider(string $provided)
+    {
+        $record = [
+            'id' => $provided,
+            'objectID' => $provided,
+            'name' => $provided,
+            'package_organisation' => preg_replace('{/.*$}', '', $provided),
+            'package_name' => preg_replace('{^[^/]*/}', '', $provided),
+            'description' => '',
+            'type' => 'virtual-package',
+            'repository' => '',
+            'language' => '',
+            'trendiness' => 100,
+            'popularity' => 4,
+            'abandoned' => 0,
+            'replacementPackage' => '',
+            'tags' => [],
+        ];
+
+        return $record;
+    }
+
+    private function getProviders($doctrine, Package $package)
+    {
+        return $doctrine->getManager()->getConnection()->fetchAll(
+            'SELECT lp.packageName
+                FROM package p
+                JOIN package_version pv ON p.id = pv.package_id
+                JOIN link_provide lp ON lp.version_id = pv.id
+                WHERE p.id = :id
+                AND pv.development = true
+                GROUP BY lp.packageName',
+            ['id' => $package->getId()]
+        );
+    }
+
+    private function getTags($doctrine, Package $package)
+    {
+        $tags = $doctrine->getManager()->getConnection()->fetchAll(
+            'SELECT t.name FROM package p
+                            JOIN package_version pv ON p.id = pv.package_id
+                            JOIN version_tag vt ON vt.version_id = pv.id
+                            JOIN tag t ON t.id = vt.tag_id
+                            WHERE p.id = :id
+                            GROUP BY t.id, t.name',
+            ['id' => $package->getId()]
+        );
+
+        foreach ($tags as $idx => $tag) {
+            $tags[$idx] = $tag['name'];
         }
 
-        $tags = array_map(function ($tag) {
+        return array_map(function ($tag) {
             return mb_strtolower(preg_replace('{[\x00-\x1f]+}u', '', $tag), 'UTF-8');
         }, $tags);
-        $document->setField('tags', $tags);
+    }
+
+    private function updateIndexedAt(array $idsToUpdate, $doctrine, string $time)
+    {
+        $retries = 5;
+        // retry loop in case of a lock timeout
+        while ($retries--) {
+            try {
+                $doctrine->getManager()->getConnection()->executeQuery(
+                    'UPDATE package SET indexedAt=:indexed WHERE id IN (:ids)',
+                    [
+                        'ids' => $idsToUpdate,
+                        'indexed' => $time,
+                    ],
+                    ['ids' => Connection::PARAM_INT_ARRAY]
+                );
+            } catch (\Exception $e) {
+                if (!$retries) {
+                    throw $e;
+                }
+                sleep(2);
+            }
+        }
     }
 }

+ 0 - 324
src/Packagist/WebBundle/Tests/Controller/WebControllerTest.php

@@ -44,253 +44,6 @@ class WebControllerTest extends WebTestCase
         $this->assertTrue($crawler->filter('.package')->count() > 0);
     }
 
-    /**
-     * @covers ::nothing
-     */
-    public function testSearchNoOrderBysAction()
-    {
-        $json = $this->commonTestSearchActionOrderBysDownloads();
-
-        $this->assertSame(
-            $this->getJsonResults(
-                array(
-                    $this->getJsonResult('twig/twig', 25, 0),
-                    $this->getJsonResult('composer/packagist', 12, 0),
-                    $this->getJsonResult('symfony/symfony', 42, 0),
-                )
-            ),
-            $json
-        );
-    }
-
-    /**
-     * @covers ::nothing
-     */
-    public function testSearchOrderByDownloadsAscAction()
-    {
-        $json = $this->commonTestSearchActionOrderBysDownloads(
-            array(
-                array(
-                    'sort' => 'downloads',
-                    'order' => 'asc',
-                ),
-            )
-        );
-
-        $this->assertSame(
-            $this->getJsonResults(
-                array(
-                    $this->getJsonResult('composer/packagist', 12, 0),
-                    $this->getJsonResult('twig/twig', 25, 0),
-                    $this->getJsonResult('symfony/symfony', 42, 0),
-                )
-            ),
-            $json
-        );
-    }
-
-    /**
-     * @covers ::nothing
-     */
-    public function testSearchOrderByDownloadsDescAction()
-    {
-        $json = $this->commonTestSearchActionOrderBysDownloads(
-            array(
-                array(
-                    'sort' => 'downloads',
-                    'order' => 'desc',
-                ),
-            )
-        );
-
-        $this->assertSame(
-            $this->getJsonResults(
-                array(
-                    $this->getJsonResult('symfony/symfony', 42, 0),
-                    $this->getJsonResult('twig/twig', 25, 0),
-                    $this->getJsonResult('composer/packagist', 12, 0),
-                )
-            ),
-            $json
-        );
-    }
-
-    /**
-     * @covers ::nothing
-     */
-    public function testSearchOrderByFaversAscAction()
-    {
-        $json = $this->commonTestSearchActionOrderBysFavers(
-            array(
-                array(
-                    'sort' => 'favers',
-                    'order' => 'asc',
-                ),
-            )
-        );
-
-        $this->assertSame(
-            $this->getJsonResults(
-                array(
-                    $this->getJsonResult('composer/packagist', 0, 1),
-                    $this->getJsonResult('twig/twig', 0, 2),
-                    $this->getJsonResult('symfony/symfony', 0, 3),
-                )
-            ),
-            $json
-        );
-    }
-
-    /**
-     * @covers ::nothing
-     */
-    public function testSearchOrderByFaversDescAction()
-    {
-        $json = $this->commonTestSearchActionOrderBysFavers(
-            array(
-                array(
-                    'sort' => 'favers',
-                    'order' => 'desc',
-                ),
-            )
-        );
-
-        $this->assertSame(
-            $this->getJsonResults(
-                array(
-                    $this->getJsonResult('symfony/symfony', 0, 3),
-                    $this->getJsonResult('twig/twig', 0, 2),
-                    $this->getJsonResult('composer/packagist', 0, 1),
-                )
-            ),
-            $json
-        );
-    }
-
-    /**
-     * @covers ::nothing
-     */
-    public function testSearchOrderBysCombinationAction()
-    {
-        $userMock = $this->createMock('Packagist\WebBundle\Entity\User');
-        $userMock1 = $this->createMock('Packagist\WebBundle\Entity\User');
-        $userMock2 = $this->createMock('Packagist\WebBundle\Entity\User');
-
-        $userMock->method('getId')->will($this->returnValue(1));
-        $userMock1->method('getId')->will($this->returnValue(2));
-        $userMock2->method('getId')->will($this->returnValue(3));
-
-        $json = $this->commonTestSearchActionOrderBysAction(
-            function (
-                ContainerInterface $container,
-                Package $twigPackage,
-                Package $packagistPackage,
-                Package $symfonyPackage
-            ) use (
-                $userMock,
-                $userMock1,
-                $userMock2
-            ) {
-                $downloadManager = $container->get('packagist.download_manager');
-
-                /* @var $downloadManager DownloadManager */
-
-                for ($i = 0; $i < 25; $i += 1) {
-                    $downloadManager->addDownloads([['id' => $twigPackage->getId(), 'vid' => 25, 'ip' => '127.0.0.'.random_int(0,255)]]);
-                }
-                for ($i = 0; $i < 12; $i += 1) {
-                    $downloadManager->addDownloads([['id' => $packagistPackage->getId(), 'vid' => 12, 'ip' => '127.0.0.'.random_int(0,255)]]);
-                }
-                for ($i = 0; $i < 25; $i += 1) {
-                    $downloadManager->addDownloads([['id' => $symfonyPackage->getId(), 'vid' => 42, 'ip' => '127.0.0.'.random_int(0,255)]]);
-                }
-
-                $favoriteManager = $container->get('packagist.favorite_manager');
-
-                /* @var $favoriteManager FavoriteManager */
-
-                $favoriteManager->markFavorite($userMock, $packagistPackage);
-
-                $favoriteManager->markFavorite($userMock, $symfonyPackage);
-                $favoriteManager->markFavorite($userMock1, $symfonyPackage);
-                $favoriteManager->markFavorite($userMock2, $symfonyPackage);
-            },
-            array(
-                array(
-                    'sort' => 'downloads',
-                    'order' => 'desc',
-                ),
-                array(
-                    'sort' => 'favers',
-                    'order' => 'desc',
-                ),
-            )
-        );
-
-        $this->assertSame(
-            $this->getJsonResults(
-                array(
-                    $this->getJsonResult('symfony/symfony', 25, 3),
-                    $this->getJsonResult('twig/twig', 25, 0),
-                    $this->getJsonResult('composer/packagist', 12, 1),
-                )
-            ),
-            $json
-        );
-    }
-
-    /**
-     * @param callable $onBeforeIndex
-     * @param array $orderBys
-     *
-     * @return array
-     */
-    protected function commonTestSearchActionOrderBysAction(
-        callable $onBeforeIndex,
-        array $orderBys = array()
-    ) {
-        $client = self::createClient();
-
-        $container = $client->getContainer();
-
-        $kernelRootDir = $container->getParameter('kernel.root_dir');
-
-        $this->executeCommand('php '.$kernelRootDir . '/console doctrine:database:drop --env=test --force', false);
-        $this->executeCommand('php '.$kernelRootDir . '/console doctrine:database:create --env=test');
-        $this->executeCommand('php '.$kernelRootDir . '/console doctrine:schema:create --env=test');
-        $this->executeCommand('php '.$kernelRootDir . '/console redis:flushall --env=test -n');
-
-        $lock = $container->getParameter('kernel.cache_dir').'/composer-indexer.lock';
-
-        $this->executeCommand('rm -f ' . $lock);
-
-        list($twigPackage, $packagistPackage, $symfonyPackage) = $this->initializePackages($container);
-
-        if (!empty($orderBys)) {
-            $orderBysQryStrPart = '&' . http_build_query(
-                array(
-                    'orderBys' => $orderBys
-                )
-            );
-        } else {
-            $orderBysQryStrPart = '';
-        }
-
-        $onBeforeIndex($container, $twigPackage, $packagistPackage, $symfonyPackage);
-
-        $this->executeCommand('php '.$kernelRootDir . '/console packagist:index --env=test --force');
-
-        $client->request('GET', '/search.json?q=' . $orderBysQryStrPart);
-
-        $response = $client->getResponse();
-
-        $content = $client->getResponse()->getContent();
-
-        $this->assertSame(200, $response->getStatusCode(), $content);
-
-        return json_decode($content, true);
-    }
-
     protected function initializePackages(ContainerInterface $container)
     {
         $kernelRootDir = $container->getParameter('kernel.root_dir');
@@ -326,83 +79,6 @@ class WebControllerTest extends WebTestCase
         return [$twigPackage, $packagistPackage, $symfonyPackage];
     }
 
-    /**
-     * @param array $orderBys
-     *
-     * @return array
-     */
-    protected function commonTestSearchActionOrderBysDownloads(
-        array $orderBys = array()
-    ) {
-        return $this->commonTestSearchActionOrderBysAction(
-            function (
-                ContainerInterface $container,
-                Package $twigPackage,
-                Package $packagistPackage,
-                Package $symfonyPackage
-            ) {
-                $downloadManager = $container->get('packagist.download_manager');
-
-                /* @var $downloadManager DownloadManager */
-
-                for ($i = 0; $i < 25; $i += 1) {
-                    $downloadManager->addDownloads([['id' => $twigPackage->getId(), 'vid' => 25, 'ip' => '127.0.0.'.random_int(0,255)]]);
-                }
-                for ($i = 0; $i < 12; $i += 1) {
-                    $downloadManager->addDownloads([['id' => $packagistPackage->getId(), 'vid' => 12, 'ip' => '127.0.0.'.random_int(0,255)]]);
-                }
-                for ($i = 0; $i < 42; $i += 1) {
-                    $downloadManager->addDownloads([['id' => $symfonyPackage->getId(), 'vid' => 42, 'ip' => '127.0.0.'.random_int(0,255)]]);
-                }
-            },
-            $orderBys
-        );
-    }
-
-    /**
-     * @param array $orderBys
-     *
-     * @return array
-     */
-    protected function commonTestSearchActionOrderBysFavers(
-        array $orderBys = array()
-    ) {
-        $userMock = $this->createMock('Packagist\WebBundle\Entity\User');
-        $userMock1 = $this->createMock('Packagist\WebBundle\Entity\User');
-        $userMock2 = $this->createMock('Packagist\WebBundle\Entity\User');
-
-        $userMock->method('getId')->will($this->returnValue(1));
-        $userMock1->method('getId')->will($this->returnValue(2));
-        $userMock2->method('getId')->will($this->returnValue(3));
-
-        return $this->commonTestSearchActionOrderBysAction(
-            function (
-                ContainerInterface $container,
-                Package $twigPackage,
-                Package $packagistPackage,
-                Package $symfonyPackage
-            ) use (
-                $userMock,
-                $userMock1,
-                $userMock2
-            ) {
-                $favoriteManager = $container->get('packagist.favorite_manager');
-
-                /* @var $favoriteManager FavoriteManager */
-
-                $favoriteManager->markFavorite($userMock, $twigPackage);
-                $favoriteManager->markFavorite($userMock1, $twigPackage);
-
-                $favoriteManager->markFavorite($userMock, $packagistPackage);
-
-                $favoriteManager->markFavorite($userMock, $symfonyPackage);
-                $favoriteManager->markFavorite($userMock1, $symfonyPackage);
-                $favoriteManager->markFavorite($userMock2, $symfonyPackage);
-            },
-            $orderBys
-        );
-    }
-
     /**
      * Executes a given command.
      *