Skip to content
GitLab
Explore
Sign in
project
facets
Compare revisions
d32ab6423327a89754eadd601d1a8469a6c845f9 to 8.x-1.0-alpha1
Hide whitespace changes
Inline
Side-by-side
src/Plugin/Block/FacetBlockDeriver.php
0 → 100644
View file @
7bd666e7
<?php
/**
* @file
* Contains Drupal\facets\Plugin\Block\FacetBlockDeriver.
*/
namespace
Drupal\facets\Plugin\Block
;
use
Drupal\Component\Plugin\PluginBase
;
use
Drupal\Core\Plugin\Discovery\ContainerDeriverInterface
;
use
Drupal\Core\StringTranslation\StringTranslationTrait
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
/**
* This deriver creates a block for every facet that has been created.
*/
class
FacetBlockDeriver
implements
ContainerDeriverInterface
{
use
StringTranslationTrait
;
/**
* List of derivative definitions.
*
* @var array
*/
protected
$derivatives
=
[];
/**
* The entity storage used for facets.
*
* @var \Drupal\Core\Entity\EntityStorageInterface $facetStorage
*/
protected
$facetStorage
;
/**
* {@inheritdoc}
*/
public
static
function
create
(
ContainerInterface
$container
,
$base_plugin_id
)
{
$deriver
=
new
static
(
$container
,
$base_plugin_id
);
$deriver
->
facetStorage
=
$container
->
get
(
'entity_type.manager'
)
->
getStorage
(
'facets_facet'
);
return
$deriver
;
}
/**
* {@inheritdoc}
*/
public
function
getDerivativeDefinition
(
$derivative_id
,
$base_plugin_definition
)
{
$derivatives
=
$this
->
getDerivativeDefinitions
(
$base_plugin_definition
);
return
isset
(
$derivatives
[
$derivative_id
])
?
$derivatives
[
$derivative_id
]
:
NULL
;
}
/**
* {@inheritdoc}
*/
public
function
getDerivativeDefinitions
(
$base_plugin_definition
)
{
$base_plugin_id
=
$base_plugin_definition
[
'id'
];
if
(
!
isset
(
$this
->
derivatives
[
$base_plugin_id
]))
{
$plugin_derivatives
=
[];
/** @var \Drupal\facets\FacetInterface[] $all_facets */
$all_facets
=
$this
->
facetStorage
->
loadMultiple
();
foreach
(
$all_facets
as
$facet
)
{
$machine_name
=
$facet
->
id
();
$plugin_derivatives
[
$machine_name
]
=
[
'id'
=>
$base_plugin_id
.
PluginBase
::
DERIVATIVE_SEPARATOR
.
$machine_name
,
'label'
=>
$this
->
t
(
'Facet: :facet'
,
[
':facet'
=>
$facet
->
getName
()]),
'admin_label'
=>
$facet
->
getName
(),
'description'
=>
$this
->
t
(
'Facet'
),
]
+
$base_plugin_definition
;
$sources
[]
=
$this
->
t
(
'Facet: :facet'
,
[
':facet'
=>
$facet
->
getName
()]);
}
$this
->
derivatives
[
$base_plugin_id
]
=
$plugin_derivatives
;
}
return
$this
->
derivatives
[
$base_plugin_id
];
}
}
src/Plugin/Condition/OtherFacet.php
0 → 100644
View file @
7bd666e7
<?php
/**
* @file
* Contains \Drupal\facets\Plugin\Condition\OtherFacet.
*/
namespace
Drupal\facets\Plugin\Condition
;
use
Drupal\Component\Plugin\PluginBase
;
use
Drupal\Core\Block\BlockManager
;
use
Drupal\Core\Condition\ConditionPluginBase
;
use
Drupal\Core\Entity\EntityStorageInterface
;
use
Drupal\Core\Form\FormStateInterface
;
use
Drupal\Core\Plugin\ContainerFactoryPluginInterface
;
use
Drupal\Core\Session\AccountProxyInterface
;
use
Drupal\facets\FacetManager\DefaultFacetManager
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
/**
* Provides an 'other facet' condition.
*
* This adds a condition plugin to make sure that facets can depend on other
* facet's or their values. The facet value is a freeform textfield and works on
* both raw and display values of the results.
*
* @Condition(
* id = "other_facet",
* label = @Translation("Other facet"),
* )
*/
class
OtherFacet
extends
ConditionPluginBase
implements
ContainerFactoryPluginInterface
{
/**
* The facet entity storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected
$facetStorage
;
/**
* The block plugin manager.
*
* @var \Drupal\Core\Block\BlockManager
*/
protected
$blockManager
;
/**
* The user that's currently logged in.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected
$currentUser
;
/**
* The facet manager service.
*
* @var \Drupal\facets\FacetManager\DefaultFacetManager
*/
protected
$facetManager
;
/**
* Creates a new instance of the condition.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $entity_storage
* The entity storage.
* @param \Drupal\Core\Block\BlockManager $block_manager
* The block plugin manager.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* The currently logged in user.
* @param \Drupal\facets\FacetManager\DefaultFacetManager $facet_manager
* The default facet manager class.
* @param array $configuration
* The plugin configuration, i.e. an array with configuration values keyed
* by configuration option name. The special key 'context' may be used to
* initialize the defined contexts by setting it to an array of context
* values keyed by context names.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
*/
public
function
__construct
(
EntityStorageInterface
$entity_storage
,
BlockManager
$block_manager
,
AccountProxyInterface
$current_user
,
DefaultFacetManager
$facet_manager
,
array
$configuration
,
$plugin_id
,
$plugin_definition
)
{
parent
::
__construct
(
$configuration
,
$plugin_id
,
$plugin_definition
);
$this
->
facetStorage
=
$entity_storage
;
$this
->
blockManager
=
$block_manager
;
$this
->
currentUser
=
$current_user
;
$this
->
facetManager
=
$facet_manager
;
}
/**
* {@inheritdoc}
*/
public
static
function
create
(
ContainerInterface
$container
,
array
$configuration
,
$plugin_id
,
$plugin_definition
)
{
return
new
static
(
$container
->
get
(
'entity_type.manager'
)
->
getStorage
(
'facets_facet'
),
$container
->
get
(
'plugin.manager.block'
),
$container
->
get
(
'current_user'
),
$container
->
get
(
'facets.manager'
),
$configuration
,
$plugin_id
,
$plugin_definition
);
}
/**
* {@inheritdoc}
*/
public
function
buildConfigurationForm
(
array
$form
,
FormStateInterface
$form_state
)
{
$options
=
[];
// Loop over all defined blocks and filter them by provider, this builds an
// array of blocks that are provided by the facets module.
foreach
(
$this
->
blockManager
->
getDefinitions
()
as
$definition
)
{
if
(
$definition
[
'provider'
]
==
'facets'
)
{
$options
[
$definition
[
'id'
]]
=
$definition
[
'label'
];
}
}
$form
[
'facets'
]
=
[
'#title'
=>
$this
->
t
(
'Other facet blocks'
),
'#type'
=>
'radios'
,
'#options'
=>
$options
,
'#default_value'
=>
$this
->
configuration
[
'facets'
],
];
$form
[
'facet_value'
]
=
[
'#title'
=>
$this
->
t
(
'Facet value'
),
'#description'
=>
$this
->
t
(
'Only applies when a facet is already selected.'
),
'#type'
=>
'textfield'
,
'#default_value'
=>
$this
->
configuration
[
'facet_value'
],
];
return
parent
::
buildConfigurationForm
(
$form
,
$form_state
);
}
/**
* {@inheritdoc}
*/
public
function
submitConfigurationForm
(
array
&
$form
,
FormStateInterface
$form_state
)
{
$this
->
configuration
[
'facets'
]
=
$form_state
->
getValue
(
'facets'
);
$this
->
configuration
[
'facet_value'
]
=
$form_state
->
getValue
(
'facet_value'
);
parent
::
submitConfigurationForm
(
$form
,
$form_state
);
}
/**
* {@inheritdoc}
*/
public
function
summary
()
{
return
$this
->
t
(
'The facet is @facet also rendered on the same page.'
,
[
'@facet'
=>
$this
->
configuration
[
'facets'
]]
);
}
/**
* {@inheritdoc}
*/
public
function
evaluate
()
{
$allowed_facet_value
=
$this
->
configuration
[
'facet_value'
];
$allowed_facets
=
$this
->
configuration
[
'facets'
];
// Return as early as possible when there are no settings for allowed
// facets.
if
(
empty
(
$allowed_facets
))
{
return
TRUE
;
}
/** @var \Drupal\facets\Plugin\Block\FacetBlock $block_plugin */
$block_plugin
=
$this
->
blockManager
->
createInstance
(
$allowed_facets
);
// Allowed facet value is not set, so we only have to check if the block is
// shown here by running the access method on the block plugin with the
// currently logged in user.
if
(
empty
(
$allowed_facet_value
))
{
return
$block_plugin
->
access
(
$this
->
currentUser
);
}
// The block plugin id is saved in the schema: BasePluginID:FacetID. This
// means we can explode the ID on ':' and the facet id is in the last part
// of that result.
$block_plugin_id
=
$block_plugin
->
getPluginId
();
$facet_id
=
explode
(
PluginBase
::
DERIVATIVE_SEPARATOR
,
$block_plugin_id
)[
1
];
/** @var \Drupal\facets\FacetInterface $facet */
$facet
=
$this
->
facetStorage
->
load
(
$facet_id
);
$this
->
facetManager
->
setFacetSourceId
(
$facet
->
getFacetSourceId
());
$facet
=
$this
->
facetManager
->
returnProcessedFacet
(
$facet_id
);
foreach
(
$facet
->
getResults
()
as
$result
)
{
$is_value
=
$result
->
getRawValue
()
==
$allowed_facet_value
||
$result
->
getDisplayValue
()
==
$allowed_facet_value
;
if
(
$is_value
&&
$result
->
isActive
())
{
return
TRUE
;
}
}
return
FALSE
;
}
/**
* {@inheritdoc}
*/
public
function
defaultConfiguration
()
{
$config
=
[
'facets'
=>
FALSE
,
'facet_value'
=>
FALSE
];
return
$config
+
parent
::
defaultConfiguration
();
}
}
src/Plugin/facets/facet_source/SearchApiBaseFacetSource.php
View file @
7bd666e7
...
...
@@ -10,7 +10,6 @@ use Drupal\Core\Form\FormStateInterface;
use
Drupal\Core\StringTranslation\StringTranslationTrait
;
use
Drupal\facets\Exception\InvalidQueryTypeException
;
use
Drupal\facets\FacetInterface
;
use
Drupal\facets\FacetSource\FacetSourcePluginInterface
;
use
Drupal\search_api
\Backend\BackendInterface
;
use
Drupal\facets\FacetSource\FacetSourcePluginBase
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
...
...
@@ -65,7 +64,7 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase {
/**
* {@inheritdoc}
*/
public
function
buildConfigurationForm
(
array
$form
,
FormStateInterface
$form_state
,
FacetInterface
$facet
,
FacetSourcePluginInterface
$facet_source
)
{
public
function
buildConfigurationForm
(
array
$form
,
FormStateInterface
$form_state
)
{
$form
[
'field_identifier'
]
=
[
'#type'
=>
'select'
,
...
...
@@ -73,7 +72,7 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase {
'#title'
=>
$this
->
t
(
'Facet field'
),
'#description'
=>
$this
->
t
(
'Choose the indexed field.'
),
'#required'
=>
TRUE
,
'#default_value'
=>
$facet
->
getFieldIdentifier
(),
'#default_value'
=>
$
this
->
facet
->
getFieldIdentifier
(),
];
return
$form
;
...
...
@@ -84,7 +83,7 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase {
*/
public
function
getFields
()
{
$indexed_fields
=
[];
$fields
=
$this
->
index
->
getFields
(
TRUE
);
$fields
=
$this
->
index
->
getFields
();
foreach
(
$fields
as
$field
)
{
$indexed_fields
[
$field
->
getFieldIdentifier
()]
=
$field
->
getLabel
();
}
...
...
@@ -99,16 +98,17 @@ abstract class SearchApiBaseFacetSource extends FacetSourcePluginBase {
// identifier.
$field_id
=
$facet
->
getFieldIdentifier
();
// Get the Search API Server.
$server
=
$this
->
index
->
getServer
();
$server
=
$this
->
index
->
getServer
Instance
();
// Get the Search API Backend.
$backend
=
$server
->
getBackend
();
$fields
=
$this
->
index
->
getFields
(
TRUE
);
$fields
=
$this
->
index
->
getFields
();
foreach
(
$fields
as
$field
)
{
if
(
$field
->
getFieldIdentifier
()
==
$field_id
)
{
return
$this
->
getQueryTypesForDataType
(
$backend
,
$field
->
getType
());
}
}
throw
new
InvalidQueryTypeException
(
$this
->
t
(
"No available query types were found for facet @facet"
,
[
'@facet'
=>
$facet
->
getName
()]));
}
...
...
src/Plugin/facets/facet_source/SearchApiViewsPage.php
View file @
7bd666e7
...
...
@@ -75,7 +75,7 @@ class SearchApiViewsPage extends SearchApiBaseFacetSource {
public
function
getPath
()
{
$view
=
Views
::
getView
(
$this
->
pluginDefinition
[
'view_id'
]);
$view
->
setDisplay
(
$this
->
pluginDefinition
[
'view_display'
]);
return
$view
->
getDisplay
()
->
get
Option
(
'p
ath
'
);
return
$view
->
getDisplay
()
->
get
P
ath
(
);
}
/**
...
...
src/Plugin/facets/processor/UrlProcessorHandler.php
0 → 100644
View file @
7bd666e7
<?php
/**
* @file
* Contains Drupal\facets\Plugin\facets\processor\UrlProcessorHandler.
*/
namespace
Drupal\facets\Plugin\facets\processor
;
use
Drupal\facets\Exception\InvalidProcessorException
;
use
Drupal\facets\FacetInterface
;
use
Drupal\facets\Processor\BuildProcessorInterface
;
use
Drupal\facets\Processor\PreQueryProcessorInterface
;
use
Drupal\facets\Processor\ProcessorPluginBase
;
/**
* The URL processor handler triggers the actual url processor.
*
* The URL processor handler allows managing the weight of the actual URL
* processor per Facet. This handler will trigger the actual.
*
* @FacetsUrlProcessor, which can be configured on the Facet source.
*
* @FacetsProcessor(
* id = "url_processor_handler",
* label = @Translation("URL handler"),
* description = @Translation("Triggers the URL processor, which is set in the Facet source configuration."),
* stages = {
* "pre_query" = 50,
* "build" = 15,
* },
* locked = true
* )
*/
class
UrlProcessorHandler
extends
ProcessorPluginBase
implements
BuildProcessorInterface
,
PreQueryProcessorInterface
{
/**
* The actual url processor used for handing urls.
*
* @var \Drupal\facets\UrlProcessor\UrlProcessorInterface
*/
protected
$processor
;
/**
* {@inheritdoc}
*/
public
function
__construct
(
array
$configuration
,
$plugin_id
,
array
$plugin_definition
)
{
parent
::
__construct
(
$configuration
,
$plugin_id
,
$plugin_definition
);
if
(
!
isset
(
$configuration
[
'facet'
])
||
!
$configuration
[
'facet'
]
instanceof
FacetInterface
)
{
throw
new
InvalidProcessorException
(
"The UrlProcessorHandler doesn't have the required 'facet' in the configuration array."
);
}
/** @var \Drupal\facets\FacetInterface $facet */
$facet
=
$configuration
[
'facet'
];
/** @var \Drupal\facets\FacetSourceInterface $fs */
$fs
=
$facet
->
getFacetSourceConfig
();
$url_processor_name
=
$fs
->
getUrlProcessorName
();
$manager
=
\Drupal
::
getContainer
()
->
get
(
'plugin.manager.facets.url_processor'
);
$this
->
processor
=
$manager
->
createInstance
(
$url_processor_name
,
[
'facet'
=>
$facet
]);
}
/**
* {@inheritdoc}
*/
public
function
build
(
FacetInterface
$facet
,
array
$results
)
{
return
$this
->
processor
->
buildUrls
(
$facet
,
$results
);
}
/**
* {@inheritdoc}
*/
public
function
preQuery
(
FacetInterface
$facet
)
{
$this
->
processor
->
setActiveItems
(
$facet
);
}
}
src/Plugin/facets/query_type/SearchApiString.php
View file @
7bd666e7
...
...
@@ -29,7 +29,7 @@ use Drupal\facets\Result\Result;
class
SearchApiString
extends
QueryTypePluginBase
{
/**
*
Holds t
he backend's native query object.
*
T
he backend's native query object.
*
* @var \Drupal\search_api\Query\QueryInterface
*/
...
...
@@ -41,11 +41,33 @@ class SearchApiString extends QueryTypePluginBase {
public
function
execute
()
{
$query
=
$this
->
query
;
// Alter the query here.
if
(
!
empty
(
$query
))
{
$options
=
&
$query
->
getOptions
();
$unfiltered_results
=
[];
// Only alter the query when there's an actual query object to alter.
if
(
!
empty
(
$query
))
{
$operator
=
$this
->
facet
->
getQueryOperator
();
$field_identifier
=
$this
->
facet
->
getFieldIdentifier
();
$exclude
=
$this
->
facet
->
getExclude
();
// Copy the query object so we can do an unfiltered query. We need to have
// this unfiltered results to make sure that the count of a facet is
// correct. The unfiltered results get returned to the facet manager, the
// facet manager will save it on facet::unfiltered_results.
$unfiltered_query
=
$query
;
$unfiltered_options
=
&
$unfiltered_query
->
getOptions
();
$unfiltered_options
[
'search_api_facets'
][
$field_identifier
]
=
array
(
'field'
=>
$field_identifier
,
'limit'
=>
50
,
'operator'
=>
'and'
,
'min_count'
=>
0
,
'missing'
=>
FALSE
,
);
$unfiltered_results
=
$unfiltered_query
->
execute
()
->
getExtraData
(
'search_api_facets'
);
// Set the options for the actual query.
$options
=
&
$query
->
getOptions
();
$options
[
'search_api_facets'
][
$field_identifier
]
=
array
(
'field'
=>
$field_identifier
,
'limit'
=>
50
,
...
...
@@ -56,25 +78,36 @@ class SearchApiString extends QueryTypePluginBase {
// Add the filter to the query if there are active values.
$active_items
=
$this
->
facet
->
getActiveItems
();
if
(
count
(
$active_items
))
{
$filter
=
$query
->
createConditionGroup
(
$operator
);
foreach
(
$active_items
as
$value
)
{
$filter
=
$query
->
createConditionGroup
();
$filter
->
addCondition
(
$this
->
facet
->
getFieldIdentifier
(),
$value
);
$query
->
addConditionGroup
(
$filter
);
$filter
->
addCondition
(
$this
->
facet
->
getFieldIdentifier
(),
$value
,
$exclude
?
'<>'
:
'='
);
}
$query
->
addConditionGroup
(
$filter
);
}
}
return
$unfiltered_results
;
}
/**
* {@inheritdoc}
*/
public
function
build
()
{
$query_operator
=
$this
->
facet
->
getQueryOperator
();
if
(
!
empty
(
$this
->
results
))
{
$facet_results
=
array
();
foreach
(
$this
->
results
as
$result
)
{
if
(
$result
[
'count'
])
{
$facet_results
[]
=
new
Result
(
trim
(
$result
[
'filter'
],
'"'
),
trim
(
$result
[
'filter'
],
'"'
),
$result
[
'count'
]);
foreach
(
$this
->
results
as
$key
=>
$result
)
{
if
(
$result
[
'count'
]
||
$query_operator
==
'OR'
)
{
$count
=
$result
[
'count'
];
if
(
$query_operator
===
'OR'
)
{
$count
=
$this
->
facet
->
getUnfilteredResults
()[
$this
->
facet
->
getFieldIdentifier
()][
$key
][
'count'
];
}
$result
=
new
Result
(
trim
(
$result
[
'filter'
],
'"'
),
trim
(
$result
[
'filter'
],
'"'
),
$count
);
$facet_results
[]
=
$result
;
}
}
$this
->
facet
->
setResults
(
$facet_results
);
...
...
src/Plugin/facets/processor/QueryString
UrlProcessor
.php
→
src/Plugin/facets/
url_
processor/QueryString.php
View file @
7bd666e7
...
...
@@ -2,31 +2,26 @@
/**
* @file
* Contains Drupal\facets\Plugin\facets\url_processor\
UrlProcessor
QueryString.
* Contains Drupal\facets\Plugin\facets\url_processor\QueryString.
*/
namespace
Drupal\facets\Plugin\facets\processor
;
namespace
Drupal\facets\Plugin\facets\
url_
processor
;
use
Drupal\Core\Url
;
use
Drupal\facets\FacetInterface
;
use
Drupal\facets\Processor\UrlProcessorPluginBase
;
use
Drupal\facets\
Url
Processor\UrlProcessorPluginBase
;
use
Symfony\Component\HttpFoundation\Request
;
/**
*
The basic url processor, uses query strings
.
*
Query string URL processor
.
*
* @FacetsProcessor(
* @Facets
Url
Processor(
* id = "query_string",
* label = @Translation("Query string url processor"),
* description = @Translation("Most simple url processor which uses the query sting."),
* stages = {
* "pre_query" = 50,
* "build" = 15,
* },
* locked = true
* label = @Translation("Query string"),
* description = @Translation("Query string is the default Facets URL processor, and uses GET parameters, e.g. ?f[0]=brand:drupal&f[1]=color:blue")
* )
*/
class
QueryString
UrlProcessor
extends
UrlProcessorPluginBase
{
class
QueryString
extends
UrlProcessorPluginBase
{
/**
* A string that separates the filters in the query string.
...
...
@@ -38,7 +33,7 @@ class QueryStringUrlProcessor extends UrlProcessorPluginBase {
*
* @var string
*/
protected
$url
_a
lias
;
protected
$url
A
lias
;
/**
* An array of active filters.
...
...
@@ -59,22 +54,21 @@ class QueryStringUrlProcessor extends UrlProcessorPluginBase {
/**
* {@inheritdoc}
*/
public
function
build
(
FacetInterface
$facet
,
array
$results
)
{
// Create links for all the values.
// First get the current list of get parameters.
$get_params
=
$this
->
request
->
query
;
// Set the url alias from the the facet object.
$this
->
url_alias
=
$facet
->
getUrlAlias
();
public
function
buildUrls
(
FacetInterface
$facet
,
array
$results
)
{
// No results are found for this facet, so don't try to create urls.
if
(
empty
(
$results
))
{
return
[];
}
// First get the current list of get parameters.
$get_params
=
$this
->
request
->
query
;
// Set the url alias from the the facet object.
$this
->
urlAlias
=
$facet
->
getUrlAlias
();
/** @var \Drupal\facets\Result\ResultInterface $result */
foreach
(
$results
as
&
$result
)
{
$filter_string
=
$this
->
url
_a
lias
.
':'
.
$result
->
getRawValue
();
$filter_string
=
$this
->
url
A
lias
.
self
::
SEPARATOR
.
$result
->
getRawValue
();
$result_get_params
=
clone
$get_params
;
$filter_params
=
$result_get_params
->
get
(
$this
->
filterKey
,
[],
TRUE
);
...
...
@@ -108,20 +102,20 @@ class QueryStringUrlProcessor extends UrlProcessorPluginBase {
/**
* {@inheritdoc}
*/
public
function
preQuery
(
FacetInterface
$facet
)
{
public
function
setActiveItems
(
FacetInterface
$facet
)
{
// Set the url alias from the the facet object.
$this
->
url
_a
lias
=
$facet
->
getUrlAlias
();
$this
->
url
A
lias
=
$facet
->
getUrlAlias
();
// Get the filter key of the facet.
if
(
isset
(
$this
->
activeFilters
[
$this
->
url
_a
lias
]))
{
foreach
(
$this
->
activeFilters
[
$this
->
url
_a
lias
]
as
$value
)
{
if
(
isset
(
$this
->
activeFilters
[
$this
->
url
A
lias
]))
{
foreach
(
$this
->
activeFilters
[
$this
->
url
A
lias
]
as
$value
)
{
$facet
->
setActiveItem
(
trim
(
$value
,
'"'
));
}
}
}
/**
* Initialize the active filters.
* Initialize
s
the active filters.
*
* Get all the filters that are active. This method only get's all the
* filters but doesn't assign them to facets. In the processFacet method the
...
...
src/Plugin/facets/widget/CheckboxWidget.php
View file @
7bd666e7
...
...
@@ -7,10 +7,13 @@
namespace
Drupal\facets\Plugin\facets\widget
;
use
Drupal\Core\Form\FormInterface
;
use
Drupal\Core\Form\FormStateInterface
;
use
Drupal\Core\StringTranslation\StringTranslationTrait
;
use
Drupal\Core\Url
;
use
Drupal\facets\FacetInterface
;
use
Drupal\facets\Widget\WidgetInterface
;
use
Symfony\Component\HttpFoundation\RedirectResponse
;
/**
* The checkbox / radios widget.
...
...
@@ -21,18 +24,10 @@ use Drupal\facets\Widget\WidgetInterface;
* description = @Translation("A configurable widget that shows a list of checkboxes"),
* )
*/
class
CheckboxWidget
implements
WidgetInterface
{
class
CheckboxWidget
implements
WidgetInterface
,
FormInterface
{
use
StringTranslationTrait
;
/**
* The link generator.
*
* @var \Drupal\Core\Utility\LinkGeneratorInterface $linkGenerator
* The link generator.
*/
protected
$linkGenerator
;
/**
* {@inheritdoc}
*/
...
...
@@ -44,33 +39,14 @@ class CheckboxWidget implements WidgetInterface {
* {@inheritdoc}
*/
public
function
build
(
FacetInterface
$facet
)
{
/** @var \Drupal\facets\Result\Result[] $results */
$results
=
$facet
->
getResults
();
$items
=
[];
$configuration
=
$facet
->
get
(
'widget_configs'
);
$show_numbers
=
(
bool
)
$configuration
[
'show_numbers'
];
$form_builder
=
\Drupal
::
getContainer
()
->
get
(
'form_builder'
);
foreach
(
$results
as
$result
)
{
if
(
$result
->
getCount
())
{
// Get the link.
$text
=
$result
->
getDisplayValue
();
if
(
$show_numbers
)
{
$text
.
=
' ('
.
$result
->
getCount
()
.
')'
;
}
if
(
$result
->
isActive
())
{
$text
=
'(-) '
.
$text
;
}
$link
=
$this
->
linkGenerator
()
->
generate
(
$text
,
$result
->
getUrl
());
$items
[]
=
$link
;
}
}
$build
=
[
'#theme'
=>
'item_list'
,
'#items'
=>
$items
,
];
// The form builder's getForm method accepts 1 argument in the interface,
// the form ID. Extra arguments get passed into the form states addBuildInfo
// method. This way we can pass the facet to the ::buildForm method, it uses
// FormState::getBuildInfo to get the facet out.
$build
=
$form_builder
->
getForm
(
static
::
class
,
$facet
);
$build
[
'#prefix'
]
=
$this
->
t
(
'Checkboxes'
);
return
$build
;
}
...
...
@@ -102,16 +78,102 @@ class CheckboxWidget implements WidgetInterface {
}
/**
* Gets the link generator.
*
* @return \Drupal\Core\Utility\LinkGeneratorInterface
* The link generator.
* {@inheritdoc}
*/
protected
function
linkGenerator
()
{
if
(
!
isset
(
$this
->
linkGenerator
))
{
$this
->
linkGenerator
=
\Drupal
::
linkGenerator
();
public
function
getFormId
()
{
return
'facets_checkbox_widget'
;
}
/**
* {@inheritdoc}
*/
public
function
buildForm
(
array
$form
,
FormStateInterface
$form_state
)
{
/** @var \Drupal\facets\FacetInterface $facet */
// Get the facet form the build info, see the remark in ::build to know
// where this comes from.
$build_info
=
$form_state
->
getBuildInfo
();
$facet
=
$build_info
[
'args'
][
0
];
/** @var \Drupal\facets\Result\Result[] $results */
$results
=
$facet
->
getResults
();
$configuration
=
$facet
->
getWidgetConfigs
();
$show_numbers
=
(
bool
)
(
isset
(
$configuration
[
'show_numbers'
])
?
$configuration
[
'show_numbers'
]
:
FALSE
);
$form
[
$facet
->
getFieldAlias
()]
=
[
'#type'
=>
'checkboxes'
,
'#title'
=>
$facet
->
getName
(),
];
$options
=
array
();
foreach
(
$results
as
$result
)
{
$text
=
$result
->
getDisplayValue
();
if
(
$show_numbers
)
{
$text
.
=
' ('
.
$result
->
getCount
()
.
')'
;
}
$options
[
$result
->
getRawValue
()]
=
$text
;
if
(
$result
->
isActive
())
{
$form
[
$facet
->
getFieldAlias
()][
'#default_value'
][]
=
$result
->
getRawValue
();
}
}
$form
[
$facet
->
getFieldAlias
()][
'#options'
]
=
$options
;
$form
[
$facet
->
id
()
.
'_submit'
]
=
[
'#type'
=>
'submit'
,
'#value'
=>
'submit'
,
];
return
$form
;
}
/**
* {@inheritdoc}
*/
public
function
validateForm
(
array
&
$form
,
FormStateInterface
$form_state
)
{}
/**
* {@inheritdoc}
*/
public
function
submitForm
(
array
&
$form
,
FormStateInterface
$form_state
)
{
$values
=
$form_state
->
getValues
();
/** @var \Drupal\facets\FacetInterface $facet */
$build_info
=
$form_state
->
getBuildInfo
();
$facet
=
$build_info
[
'args'
][
0
];
$result_link
=
FALSE
;
$active_items
=
[];
foreach
(
$values
[
$facet
->
getFieldAlias
()]
as
$key
=>
$value
)
{
if
(
$value
!==
0
)
{
$active_items
[]
=
$value
;
}
}
return
$this
->
linkGenerator
;
foreach
(
$facet
->
getResults
()
as
$result
)
{
if
(
in_array
(
$result
->
getRawValue
(),
$active_items
))
{
$result_link
=
$result
->
getUrl
();
}
}
// We have an active item, so we redirect to the page that has that facet
// selected. This should be an absolute link because RedirectResponse is a
// symfony class that requires a full URL.
if
(
$result_link
instanceof
Url
)
{
$result_link
->
setAbsolute
();
$form_state
->
setResponse
(
new
RedirectResponse
(
$result_link
->
toString
()));
return
;
}
// The form was submitted but nothing was active in the form, we should
// still redirect, but the url for the new page can't come from a result.
// So we're redirecting to the facet source's page.
$link
=
Url
::
fromUri
(
$facet
->
getFacetSource
()
->
getPath
());
$link
->
setAbsolute
();
$form_state
->
setResponse
(
new
RedirectResponse
(
$link
->
toString
()));
}
}
src/Plugin/facets/widget/LinksWidget.php
View file @
7bd666e7
...
...
@@ -8,6 +8,7 @@
namespace
Drupal\facets\Plugin\facets\widget
;
use
Drupal\Core\Form\FormStateInterface
;
use
Drupal\Core\Link
;
use
Drupal\Core\StringTranslation\StringTranslationTrait
;
use
Drupal\facets\FacetInterface
;
use
Drupal\facets\Widget\WidgetInterface
;
...
...
@@ -25,14 +26,6 @@ class LinksWidget implements WidgetInterface {
use
StringTranslationTrait
;
/**
* The link generator.
*
* @var \Drupal\Core\Utility\LinkGeneratorInterface $linkGenerator
* The link generator.
*/
protected
$linkGenerator
;
/**
* {@inheritdoc}
*/
...
...
@@ -48,32 +41,36 @@ class LinksWidget implements WidgetInterface {
$results
=
$facet
->
getResults
();
$items
=
[];
$configuration
=
$facet
->
get
(
'w
idget
_c
onfigs
'
);
$show_numbers
=
(
bool
)
$configuration
[
'show_numbers'
];
$configuration
=
$facet
->
get
W
idget
C
onfigs
(
);
$show_numbers
=
empty
(
$configuration
[
'show_numbers'
])
?
FALSE
:
(
bool
)
$configuration
[
'show_numbers'
];
foreach
(
$results
as
$result
)
{
if
(
$result
->
getCount
())
{
// Get the link.
$text
=
$result
->
getDisplayValue
();
if
(
$show_numbers
)
{
$text
.
=
' ('
.
$result
->
getCount
()
.
')'
;
}
if
(
$result
->
isActive
())
{
$text
=
'(-) '
.
$text
;
}
if
(
is_null
(
$result
->
getUrl
()))
{
$items
[]
=
$text
;
}
else
{
$items
[]
=
$this
->
linkGenerator
()
->
generate
(
$text
,
$result
->
getUrl
());
}
// Get the link.
$text
=
$result
->
getDisplayValue
();
if
(
$show_numbers
)
{
$text
.
=
' ('
.
$result
->
getCount
()
.
')'
;
}
if
(
$result
->
isActive
())
{
$text
=
'(-) '
.
$text
;
}
if
(
is_null
(
$result
->
getUrl
()))
{
$items
[]
=
$text
;
}
else
{
$items
[]
=
new
Link
(
$text
,
$result
->
getUrl
());
}
}
$build
=
[
'#theme'
=>
'item_list'
,
'#items'
=>
$items
,
'#cache'
=>
[
'contexts'
=>
[
'url.path'
,
'url.query_args'
,
],
],
];
return
$build
;
}
...
...
@@ -107,17 +104,4 @@ class LinksWidget implements WidgetInterface {
return
$query_types
[
'string'
];
}
/**
* Gets the link generator.
*
* @return \Drupal\Core\Utility\LinkGeneratorInterface
* The link generator.
*/
protected
function
linkGenerator
()
{
if
(
!
isset
(
$this
->
linkGenerator
))
{
$this
->
linkGenerator
=
\Drupal
::
linkGenerator
();
}
return
$this
->
linkGenerator
;
}
}
src/Processor/BuildProcessorInterface.php
View file @
7bd666e7
...
...
@@ -16,7 +16,7 @@ use Drupal\facets\FacetInterface;
interface
BuildProcessorInterface
extends
ProcessorInterface
{
/**
*
Processor r
uns before the renderable array is created.
*
R
uns before the renderable array is created.
*
* @param \Drupal\facets\FacetInterface $facet
* The facet being changed.
...
...
src/Processor/PostQueryProcessorInterface.php
View file @
7bd666e7
...
...
@@ -14,7 +14,7 @@ namespace Drupal\facets\Processor;
interface
PostQueryProcessorInterface
extends
ProcessorInterface
{
/**
*
Processor r
uns after the query was executed.
*
R
uns after the query was executed.
*
* Uses the query results and can alter those results, for example a
* ValueCallbackProcessor.
...
...
src/Processor/PreQueryProcessorInterface.php
View file @
7bd666e7
...
...
@@ -15,7 +15,7 @@ use Drupal\facets\FacetInterface;
interface
PreQueryProcessorInterface
extends
ProcessorInterface
{
/**
*
Processor r
uns before the query is executed.
*
R
uns before the query is executed.
*
* Uses the queryType and the facetSource implementation to make sure the
* alteration to the query was added before the query is executed in the
...
...
src/Processor/ProcessorPluginBase.php
View file @
7bd666e7
...
...
@@ -28,8 +28,7 @@ class ProcessorPluginBase extends PluginBase implements ProcessorInterface {
/**
* {@inheritdoc}
*/
public
function
validateConfigurationForm
(
array
$form
,
FormStateInterface
$form_state
,
FacetInterface
$facet
)
{
}
public
function
validateConfigurationForm
(
array
$form
,
FormStateInterface
$form_state
,
FacetInterface
$facet
)
{}
/**
* {@inheritdoc}
...
...
src/Processor/WidgetOrderPluginBase.php
View file @
7bd666e7
...
...
@@ -11,7 +11,7 @@ use Drupal\Core\Form\FormStateInterface;
use
Drupal\facets\FacetInterface
;
/**
* A base class for plugins that implements
most of th
e boilerplate.
* A base class for plugins that implements
som
e boilerplate
for a widget order
.
*/
abstract
class
WidgetOrderPluginBase
extends
ProcessorPluginBase
implements
WidgetOrderProcessorInterface
{
...
...
src/Processor/WidgetOrderProcessorInterface.php
View file @
7bd666e7
...
...
@@ -13,7 +13,7 @@ namespace Drupal\facets\Processor;
interface
WidgetOrderProcessorInterface
extends
BuildProcessorInterface
{
/**
* Order results and return the new order of results.
* Order
s
results and return the new order of results.
*
* @param \Drupal\facets\Result\Result[] $results
* An array containing results.
...
...
src/QueryType/QueryTypeInterface.php
View file @
7bd666e7
...
...
@@ -12,12 +12,15 @@ namespace Drupal\facets\QueryType;
interface
QueryTypeInterface
{
/**
* Add facet info to the query using the backend native query object.
* Adds facet info to the query using the backend native query object.
*
* @return array
* Returns an array of unfiltered results
*/
public
function
execute
();
/**
* Build the facet information, so it can be rendered.
* Build
s
the facet information, so it can be rendered.
*/
public
function
build
();
...
...
src/QueryType/QueryTypePluginBase.php
View file @
7bd666e7
...
...
@@ -28,7 +28,7 @@ abstract class QueryTypePluginBase extends PluginBase implements QueryTypeInterf
}
/**
*
Holds t
he backend native query object.
*
T
he backend native query object.
*
* @var \Drupal\search_api\Query\Query $query
*/
...
...
@@ -42,7 +42,7 @@ abstract class QueryTypePluginBase extends PluginBase implements QueryTypeInterf
protected
$facet
;
/**
*
Holds t
he results for the facet.
*
T
he results for the facet.
*
* @var \Drupal\facets\Result\ResultInterface[]
*/
...
...
src/Result/Result.php
View file @
7bd666e7
...
...
@@ -45,7 +45,7 @@ class Result implements ResultInterface {
protected
$active
=
FALSE
;
/**
* Construct a new
instance of the
value object.
* Construct
s
a new
result
value object.
*
* @param mixed $raw_value
* The raw value.
...
...
src/Result/ResultInterface.php
View file @
7bd666e7
...
...
@@ -15,7 +15,7 @@ use Drupal\Core\Url;
interface
ResultInterface
{
/**
*
G
et the raw value as present in the index.
*
R
et
urns
the raw value as present in the index.
*
* @return string
* The raw value of the result.
...
...
@@ -23,7 +23,7 @@ interface ResultInterface {
public
function
getRawValue
();
/**
*
G
et the display value as present in the index.
*
R
et
urns
the display value as present in the index.
*
* @return string
* The formatted value of the result.
...
...
@@ -31,7 +31,7 @@ interface ResultInterface {
public
function
getDisplayValue
();
/**
*
G
et the count for the result.
*
R
et
urns
the count for the result.
*
* @return mixed
* The amount of items for the result.
...
...
@@ -39,7 +39,7 @@ interface ResultInterface {
public
function
getCount
();
/**
*
G
et the url.
*
R
et
urns
the url.
*
* @return \Drupal\Core\Url
* The url of the search page with the facet url appended.
...
...
@@ -47,7 +47,7 @@ interface ResultInterface {
public
function
getUrl
();
/**
* Set the url.
* Set
s
the url.
*
* @param \Drupal\Core\Url $url
* The url of the search page with the facet url appended.
...
...
@@ -55,7 +55,7 @@ interface ResultInterface {
public
function
setUrl
(
Url
$url
);
/**
* Indicate that the value is active (selected).
* Indicate
s
that the value is active (selected).
*
* @param bool $active
* A boolean indicating the active state.
...
...
@@ -71,7 +71,7 @@ interface ResultInterface {
public
function
isActive
();
/**
* Override the display value of a result.
* Override
s
the display value of a result.
*
* @param string $display_value
* Override display value.
...
...
src/Tests/ExampleContentTrait.php
View file @
7bd666e7
...
...
@@ -8,7 +8,6 @@
namespace
Drupal\facets\Tests
;
use
Drupal\search_api
\Entity\Index
;
use
Drupal\search_api
\Utility
;
/**
* Contains helpers to create data that can be used by tests.
...
...
@@ -36,44 +35,45 @@ trait ExampleContentTrait {
protected
function
insertExampleContent
()
{
$count
=
\Drupal
::
entityQuery
(
'entity_test'
)
->
count
()
->
execute
();
$entity_test_storage
=
\Drupal
::
entityManager
()
->
getStorage
(
'entity_test'
);
$entity_test_storage
=
\Drupal
::
entityTypeManager
()
->
getStorage
(
'entity_test'
);
$this
->
entities
[
1
]
=
$entity_test_storage
->
create
(
array
(
'name'
=>
'foo bar baz'
,
'body'
=>
'test test'
,
'type'
=>
'item'
,
'keywords'
=>
array
(
'orange'
),
'category'
=>
'item_category'
));
'name'
=>
'foo bar baz'
,
'body'
=>
'test test'
,
'type'
=>
'item'
,
'keywords'
=>
array
(
'orange'
),
'category'
=>
'item_category'
,
));
$this
->
entities
[
1
]
->
save
();
$this
->
entities
[
2
]
=
$entity_test_storage
->
create
(
array
(
'name'
=>
'foo test'
,
'body'
=>
'bar test'
,
'type'
=>
'item'
,
'keywords'
=>
array
(
'orange'
,
'apple'
,
'grape'
),
'category'
=>
'item_category'
));
'name'
=>
'foo test'
,
'body'
=>
'bar test'
,
'type'
=>
'item'
,
'keywords'
=>
array
(
'orange'
,
'apple'
,
'grape'
),
'category'
=>
'item_category'
,
));
$this
->
entities
[
2
]
->
save
();
$this
->
entities
[
3
]
=
$entity_test_storage
->
create
(
array
(
'name'
=>
'bar'
,
'body'
=>
'test foobar'
,
'type'
=>
'item'
,
));
'name'
=>
'bar'
,
'body'
=>
'test foobar'
,
'type'
=>
'item'
,
));
$this
->
entities
[
3
]
->
save
();
$this
->
entities
[
4
]
=
$entity_test_storage
->
create
(
array
(
'name'
=>
'foo baz'
,
'body'
=>
'test test test'
,
'type'
=>
'article'
,
'keywords'
=>
array
(
'apple'
,
'strawberry'
,
'grape'
),
'category'
=>
'article_category'
));
'name'
=>
'foo baz'
,
'body'
=>
'test test test'
,
'type'
=>
'article'
,
'keywords'
=>
array
(
'apple'
,
'strawberry'
,
'grape'
),
'category'
=>
'article_category'
,
));
$this
->
entities
[
4
]
->
save
();
$this
->
entities
[
5
]
=
$entity_test_storage
->
create
(
array
(
'name'
=>
'bar baz'
,
'body'
=>
'foo'
,
'type'
=>
'article'
,
'keywords'
=>
array
(
'orange'
,
'strawberry'
,
'grape'
,
'banana'
),
'category'
=>
'article_category'
));
'name'
=>
'bar baz'
,
'body'
=>
'foo'
,
'type'
=>
'article'
,
'keywords'
=>
array
(
'orange'
,
'strawberry'
,
'grape'
,
'banana'
),
'category'
=>
'article_category'
,
));
$this
->
entities
[
5
]
->
save
();
$count
=
\Drupal
::
entityQuery
(
'entity_test'
)
->
count
()
->
execute
()
-
$count
;
$this
->
assertEqual
(
$count
,
5
,
"
$count
items inserted."
);
...
...
@@ -89,37 +89,9 @@ trait ExampleContentTrait {
* The number of successfully indexed items.
*/
protected
function
indexItems
(
$index_id
)
{
/** @var \Drupal\search_api\IndexInterface $index */
$index
=
Index
::
load
(
$index_id
);
return
$index
->
indexItems
();
}
/**
* Returns the internal field ID for the given entity field name.
*
* @param string $field_name
* The field name.
*
* @return string
* The internal field ID.
*/
protected
function
getFieldId
(
$field_name
)
{
return
Utility
::
createCombinedId
(
'entity:entity_test'
,
$field_name
);
}
/**
* Returns the item IDs for the given entity IDs.
*
* @param array $entity_ids
* An array of entity IDs.
*
* @return string[]
* An array of item IDs.
*/
protected
function
getItemIds
(
array
$entity_ids
)
{
$translate_ids
=
function
(
$entity_id
)
{
return
Utility
::
createCombinedId
(
'entity:entity_test'
,
$entity_id
.
':en'
);
};
return
array_map
(
$translate_ids
,
$entity_ids
);
}
}
Prev
1
2
3
4
5
Next